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:
-rw-r--r--.clang-tidy7
-rw-r--r--.git-blame-ignore-revs77
-rw-r--r--CMakeLists.txt19
-rw-r--r--GNUmakefile13
-rw-r--r--build_files/build_environment/CMakeLists.txt1
-rw-r--r--build_files/build_environment/cmake/haru.cmake46
-rw-r--r--build_files/build_environment/cmake/harvest.cmake4
-rw-r--r--build_files/build_environment/cmake/numpy.cmake1
-rw-r--r--build_files/build_environment/cmake/opencolorio.cmake4
-rw-r--r--build_files/build_environment/cmake/python.cmake5
-rw-r--r--build_files/build_environment/cmake/python_site_packages.cmake6
-rw-r--r--build_files/build_environment/cmake/ssl.cmake2
-rw-r--r--build_files/build_environment/cmake/versions.cmake33
-rwxr-xr-xbuild_files/build_environment/install_deps.sh729
-rw-r--r--build_files/build_environment/patches/haru.diff12
-rw-r--r--build_files/build_environment/patches/python_linux.diff26
-rw-r--r--build_files/build_environment/patches/python_macos.diff289
-rw-r--r--build_files/cmake/Modules/FindAudaspace.cmake2
-rw-r--r--build_files/cmake/Modules/FindClangTidy.cmake2
-rw-r--r--build_files/cmake/Modules/FindEmbree.cmake8
-rw-r--r--build_files/cmake/Modules/FindHaru.cmake64
-rw-r--r--build_files/cmake/Modules/GTest.cmake4
-rw-r--r--build_files/cmake/Modules/GTestTesting.cmake4
-rw-r--r--build_files/cmake/config/blender_full.cmake1
-rw-r--r--build_files/cmake/config/blender_lite.cmake1
-rw-r--r--build_files/cmake/config/blender_release.cmake1
-rw-r--r--build_files/cmake/macros.cmake8
-rw-r--r--build_files/cmake/platform/platform_apple.cmake14
-rw-r--r--build_files/cmake/platform/platform_unix.cmake10
-rw-r--r--build_files/cmake/platform/platform_win32.cmake12
-rwxr-xr-xbuild_files/utils/make_update.py8
-rw-r--r--doc/doxygen/Doxyfile2
-rwxr-xr-xdoc/manpage/blender.1.py5
-rwxr-xr-xdoc/python_api/sphinx_doc_gen.sh2
-rw-r--r--extern/mantaflow/CMakeLists.txt2
-rw-r--r--extern/quadriflow/CMakeLists.txt2
-rw-r--r--intern/cycles/app/cycles_cubin_cc.cpp2
-rw-r--r--intern/cycles/blender/addon/__init__.py1
-rw-r--r--intern/cycles/blender/blender_curves.cpp49
-rw-r--r--intern/cycles/blender/blender_device.cpp8
-rw-r--r--intern/cycles/blender/blender_geometry.cpp39
-rw-r--r--intern/cycles/blender/blender_mesh.cpp133
-rw-r--r--intern/cycles/blender/blender_object.cpp10
-rw-r--r--intern/cycles/blender/blender_particles.cpp6
-rw-r--r--intern/cycles/blender/blender_python.cpp15
-rw-r--r--intern/cycles/blender/blender_session.cpp16
-rw-r--r--intern/cycles/blender/blender_session.h2
-rw-r--r--intern/cycles/blender/blender_shader.cpp159
-rw-r--r--intern/cycles/blender/blender_sync.cpp48
-rw-r--r--intern/cycles/blender/blender_sync.h1
-rw-r--r--intern/cycles/blender/blender_util.h16
-rw-r--r--intern/cycles/blender/blender_volume.cpp8
-rw-r--r--intern/cycles/bvh/bvh_build.cpp4
-rw-r--r--intern/cycles/cmake/external_libs.cmake2
-rw-r--r--intern/cycles/device/cuda/device_cuda_impl.cpp2
-rw-r--r--intern/cycles/device/device_memory.h69
-rw-r--r--intern/cycles/device/device_multi.cpp2
-rw-r--r--intern/cycles/device/device_network.h2
-rw-r--r--intern/cycles/device/opencl/device_opencl.h6
-rw-r--r--intern/cycles/device/opencl/device_opencl_impl.cpp2
-rw-r--r--intern/cycles/kernel/bvh/bvh_types.h2
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h2
-rw-r--r--intern/cycles/kernel/filter/filter_transform_gpu.h4
-rw-r--r--intern/cycles/kernel/filter/filter_transform_sse.h2
-rw-r--r--intern/cycles/kernel/geom/geom_object.h4
-rw-r--r--intern/cycles/kernel/kernel_bake.h2
-rw-r--r--intern/cycles/kernel/kernel_film.h4
-rw-r--r--intern/cycles/kernel/kernel_jitter.h4
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h2
-rw-r--r--intern/cycles/kernel/kernel_random.h2
-rw-r--r--intern/cycles/kernel/kernel_types.h4
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h2
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h2
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp2
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp2
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl2
-rw-r--r--intern/cycles/kernel/split/kernel_branched.h2
-rw-r--r--intern/cycles/kernel/split/kernel_do_volume.h2
-rw-r--r--intern/cycles/kernel/split/kernel_enqueue_inactive.h2
-rw-r--r--intern/cycles/kernel/split/kernel_shader_setup.h2
-rw-r--r--intern/cycles/kernel/svm/svm_hsv.h4
-rw-r--r--intern/cycles/kernel/svm/svm_image.h2
-rw-r--r--intern/cycles/kernel/svm/svm_noise.h4
-rw-r--r--intern/cycles/kernel/svm/svm_types.h4
-rw-r--r--intern/cycles/render/CMakeLists.txt14
-rw-r--r--intern/cycles/render/alembic.cpp1881
-rw-r--r--intern/cycles/render/alembic.h404
-rw-r--r--intern/cycles/render/attribute.cpp68
-rw-r--r--intern/cycles/render/attribute.h10
-rw-r--r--intern/cycles/render/background.cpp5
-rw-r--r--intern/cycles/render/bake.cpp20
-rw-r--r--intern/cycles/render/bake.h5
-rw-r--r--intern/cycles/render/buffers.cpp2
-rw-r--r--intern/cycles/render/camera.cpp6
-rw-r--r--intern/cycles/render/colorspace.cpp2
-rw-r--r--intern/cycles/render/denoising.cpp2
-rw-r--r--intern/cycles/render/film.cpp8
-rw-r--r--intern/cycles/render/geometry.cpp537
-rw-r--r--intern/cycles/render/geometry.h38
-rw-r--r--intern/cycles/render/graph.cpp2
-rw-r--r--intern/cycles/render/hair.cpp33
-rw-r--r--intern/cycles/render/hair.h2
-rw-r--r--intern/cycles/render/image.cpp24
-rw-r--r--intern/cycles/render/image.h5
-rw-r--r--intern/cycles/render/integrator.cpp88
-rw-r--r--intern/cycles/render/integrator.h15
-rw-r--r--intern/cycles/render/light.cpp33
-rw-r--r--intern/cycles/render/light.h23
-rw-r--r--intern/cycles/render/merge.cpp6
-rw-r--r--intern/cycles/render/mesh.cpp44
-rw-r--r--intern/cycles/render/mesh.h2
-rw-r--r--intern/cycles/render/nodes.h2
-rw-r--r--intern/cycles/render/object.cpp144
-rw-r--r--intern/cycles/render/object.h28
-rw-r--r--intern/cycles/render/osl.cpp10
-rw-r--r--intern/cycles/render/particles.cpp15
-rw-r--r--intern/cycles/render/particles.h6
-rw-r--r--intern/cycles/render/procedural.cpp89
-rw-r--r--intern/cycles/render/procedural.h73
-rw-r--r--intern/cycles/render/scene.cpp114
-rw-r--r--intern/cycles/render/scene.h15
-rw-r--r--intern/cycles/render/session.cpp8
-rw-r--r--intern/cycles/render/shader.cpp62
-rw-r--r--intern/cycles/render/shader.h23
-rw-r--r--intern/cycles/render/stats.cpp2
-rw-r--r--intern/cycles/render/stats.h1
-rw-r--r--intern/cycles/render/svm.cpp6
-rw-r--r--intern/cycles/render/tables.cpp15
-rw-r--r--intern/cycles/render/tables.h5
-rw-r--r--intern/cycles/subd/subd_split.cpp4
-rw-r--r--intern/cycles/subd/subd_split.h2
-rw-r--r--intern/cycles/util/util_array.h8
-rw-r--r--intern/cycles/util/util_math.h6
-rw-r--r--intern/cycles/util/util_math_fast.h4
-rw-r--r--intern/cycles/util/util_math_matrix.h2
-rw-r--r--intern/cycles/util/util_md5.h2
-rw-r--r--intern/cycles/util/util_stack_allocator.h2
-rw-r--r--intern/cycles/util/util_string.h4
-rw-r--r--intern/cycles/util/util_tbb.h7
-rw-r--r--intern/ffmpeg/ffmpeg_compat.h26
-rw-r--r--intern/ghost/GHOST_C-api.h17
-rw-r--r--intern/ghost/GHOST_Types.h2
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp21
-rw-r--r--intern/ghost/intern/GHOST_Context.h4
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.h4
-rw-r--r--intern/ghost/intern/GHOST_ContextD3D.h4
-rw-r--r--intern/ghost/intern/GHOST_Debug.h2
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.cpp2
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.h12
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp58
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h2
-rw-r--r--intern/ghost/intern/GHOST_Window.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp127
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h10
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp63
-rw-r--r--intern/ghost/intern/GHOST_XrGraphicsBinding.cpp2
-rw-r--r--intern/ghost/intern/GHOST_XrSession.cpp6
-rw-r--r--intern/ghost/test/CMakeLists.txt2
-rw-r--r--intern/ghost/test/gears/GHOST_C-Test.c4
-rw-r--r--intern/ghost/test/multitest/MultiTest.c6
-rw-r--r--intern/guardedalloc/CMakeLists.txt6
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h6
-rw-r--r--intern/guardedalloc/intern/mmap_win.c294
-rw-r--r--intern/iksolver/intern/IK_QJacobian.cpp4
-rw-r--r--intern/libmv/libmv/numeric/numeric.h2
-rw-r--r--intern/mikktspace/mikktspace.c6
-rw-r--r--release/darwin/Blender.app/Contents/Info.plist33
-rw-r--r--release/darwin/Blender.app/Contents/Resources/blender file icon.icnsbin284786 -> 0 bytes
-rw-r--r--release/datafiles/splash.pngbin887863 -> 737984 bytes
-rw-r--r--release/datafiles/userdef/userdef_default.c3
-rw-r--r--release/datafiles/userdef/userdef_default_theme.c13
-rw-r--r--release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py13
-rw-r--r--release/scripts/modules/bpy/path.py11
-rw-r--r--release/scripts/modules/bpy/utils/__init__.py4
-rw-r--r--release/scripts/modules/bpy_types.py1
-rw-r--r--release/scripts/presets/cloth/Cotton.py (renamed from release/scripts/presets/cloth/cotton.py)0
-rw-r--r--release/scripts/presets/cloth/Denim.py (renamed from release/scripts/presets/cloth/denim.py)0
-rw-r--r--release/scripts/presets/cloth/Leather.py (renamed from release/scripts/presets/cloth/leather.py)0
-rw-r--r--release/scripts/presets/cloth/Rubber.py (renamed from release/scripts/presets/cloth/rubber.py)0
-rw-r--r--release/scripts/presets/cloth/Silk.py (renamed from release/scripts/presets/cloth/silk.py)0
-rw-r--r--release/scripts/presets/cycles/integrator/Direct_Light.py (renamed from release/scripts/presets/cycles/integrator/direct_light.py)0
-rw-r--r--release/scripts/presets/cycles/integrator/Full_Global_Illumination.py (renamed from release/scripts/presets/cycles/integrator/full_global_illumination.py)0
-rw-r--r--release/scripts/presets/cycles/integrator/Limited_Global_Illumination.py (renamed from release/scripts/presets/cycles/integrator/limited_global_illumination.py)0
-rw-r--r--release/scripts/presets/cycles/sampling/Final.py (renamed from release/scripts/presets/cycles/sampling/final.py)0
-rw-r--r--release/scripts/presets/cycles/sampling/Preview.py (renamed from release/scripts/presets/cycles/sampling/preview.py)0
-rw-r--r--release/scripts/presets/ffmpeg/H264_in_MP4.py (renamed from release/scripts/presets/ffmpeg/h264_in_MP4.py)0
-rw-r--r--release/scripts/presets/ffmpeg/H264_in_Matroska.py (renamed from release/scripts/presets/ffmpeg/h264_in_Matroska.py)0
-rw-r--r--release/scripts/presets/ffmpeg/H264_in_Matroska_for_scrubbing.py (renamed from release/scripts/presets/ffmpeg/h264_in_Matroska_for_scrubbing.py)0
-rw-r--r--release/scripts/presets/ffmpeg/Ogg_Theora.py (renamed from release/scripts/presets/ffmpeg/ogg_theora.py)0
-rw-r--r--release/scripts/presets/ffmpeg/Xvid.py (renamed from release/scripts/presets/ffmpeg/xvid.py)0
-rw-r--r--release/scripts/presets/fluid/Honey.py (renamed from release/scripts/presets/fluid/honey.py)0
-rw-r--r--release/scripts/presets/fluid/Oil.py (renamed from release/scripts/presets/fluid/oil.py)0
-rw-r--r--release/scripts/presets/fluid/Water.py (renamed from release/scripts/presets/fluid/water.py)0
-rw-r--r--release/scripts/presets/gpencil_material/Fill_Only.py (renamed from release/scripts/presets/gpencil_material/fill_only.py)0
-rw-r--r--release/scripts/presets/gpencil_material/Stroke_Only.py (renamed from release/scripts/presets/gpencil_material/stroke_only.py)0
-rw-r--r--release/scripts/presets/gpencil_material/Stroke_and_Fill.py (renamed from release/scripts/presets/gpencil_material/stroke_and_fill.py)0
-rw-r--r--release/scripts/presets/hair_dynamics/Default.py (renamed from release/scripts/presets/hair_dynamics/default.py)0
-rw-r--r--release/scripts/presets/interface_theme/Blender_Dark.xml (renamed from release/scripts/presets/interface_theme/blender_dark.xml)0
-rw-r--r--release/scripts/presets/interface_theme/Blender_Light.xml (renamed from release/scripts/presets/interface_theme/blender_light.xml)24
-rw-r--r--release/scripts/presets/keyconfig/Blender.py (renamed from release/scripts/presets/keyconfig/blender.py)0
-rw-r--r--release/scripts/presets/keyconfig/Blender_27x.py (renamed from release/scripts/presets/keyconfig/blender_27x.py)25
-rw-r--r--release/scripts/presets/keyconfig/Industry_Compatible.py (renamed from release/scripts/presets/keyconfig/industry_compatible.py)0
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py2
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py2
-rw-r--r--release/scripts/presets/render/4K_UHDTV_2160p.py (renamed from release/scripts/presets/render/4k_UHDTV_2160p.py)0
-rw-r--r--release/scripts/presets/tracking_settings/Blurry_Footage.py (renamed from release/scripts/presets/tracking_settings/blurry_footage.py)0
-rw-r--r--release/scripts/presets/tracking_settings/Default.py (renamed from release/scripts/presets/tracking_settings/default.py)0
-rw-r--r--release/scripts/presets/tracking_settings/Fast_Motion.py (renamed from release/scripts/presets/tracking_settings/fast_motion.py)0
-rw-r--r--release/scripts/presets/tracking_settings/Planar.py (renamed from release/scripts/presets/tracking_settings/planar.py)0
-rw-r--r--release/scripts/presets/tracking_track_color/Default.py (renamed from release/scripts/presets/tracking_track_color/default.py)0
-rw-r--r--release/scripts/presets/tracking_track_color/Far_Plane.py (renamed from release/scripts/presets/tracking_track_color/far_plane.py)0
-rw-r--r--release/scripts/presets/tracking_track_color/Near_Plane.py (renamed from release/scripts/presets/tracking_track_color/near_plane.py)0
-rw-r--r--release/scripts/presets/tracking_track_color/Object.py (renamed from release/scripts/presets/tracking_track_color/object.py)0
-rw-r--r--release/scripts/startup/bl_operators/presets.py4
-rw-r--r--release/scripts/startup/bl_operators/wm.py24
-rw-r--r--release/scripts/startup/bl_ui/properties_data_gpencil.py13
-rw-r--r--release/scripts/startup/bl_ui/properties_data_volume.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py40
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_field.py7
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py6
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py8
-rw-r--r--release/scripts/startup/bl_ui/space_image.py9
-rw-r--r--release/scripts/startup/bl_ui/space_node.py10
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py3
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py169
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py51
-rw-r--r--release/scripts/startup/nodeitems_builtins.py10
-rw-r--r--release/windows/batch/blender_debug_gpu.cmd2
-rw-r--r--source/blender/CMakeLists.txt1
-rw-r--r--source/blender/blendthumb/src/Dll.cpp2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h3
-rw-r--r--source/blender/blenkernel/BKE_attribute_access.hh5
-rw-r--r--source/blender/blenkernel/BKE_attribute_math.hh256
-rw-r--r--source/blender/blenkernel/BKE_blender_undo.h4
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h6
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h15
-rw-r--r--source/blender/blenkernel/BKE_effect.h3
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh97
-rw-r--r--source/blender/blenkernel/BKE_global.h21
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h19
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h5
-rw-r--r--source/blender/blenkernel/BKE_gpencil_modifier.h2
-rw-r--r--source/blender/blenkernel/BKE_idtype.h9
-rw-r--r--source/blender/blenkernel/BKE_keyconfig.h4
-rw-r--r--source/blender/blenkernel/BKE_lib_id.h2
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h9
-rw-r--r--source/blender/blenkernel/BKE_lib_query.h2
-rw-r--r--source/blender/blenkernel/BKE_main.h50
-rw-r--r--source/blender/blenkernel/BKE_mask.h12
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h51
-rw-r--r--source/blender/blenkernel/BKE_paint.h4
-rw-r--r--source/blender/blenkernel/BKE_screen.h44
-rw-r--r--source/blender/blenkernel/BKE_shader_fx.h2
-rw-r--r--source/blender/blenkernel/BKE_softbody.h4
-rw-r--r--source/blender/blenkernel/BKE_subdiv_ccg.h2
-rw-r--r--source/blender/blenkernel/BKE_tracking.h33
-rw-r--r--source/blender/blenkernel/BKE_undo_system.h27
-rw-r--r--source/blender/blenkernel/BKE_volume.h2
-rw-r--r--source/blender/blenkernel/BKE_volume_to_mesh.hh (renamed from intern/guardedalloc/mmap_win.h)49
-rw-r--r--source/blender/blenkernel/CMakeLists.txt14
-rw-r--r--source/blender/blenkernel/intern/action.c22
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c840
-rw-r--r--source/blender/blenkernel/intern/armature.c9
-rw-r--r--source/blender/blenkernel/intern/armature_update.c6
-rw-r--r--source/blender/blenkernel/intern/asset.cc (renamed from source/blender/blenkernel/intern/asset.c)16
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc1424
-rw-r--r--source/blender/blenkernel/intern/attribute_math.cc58
-rw-r--r--source/blender/blenkernel/intern/blender_undo.c5
-rw-r--r--source/blender/blenkernel/intern/blendfile.c7
-rw-r--r--source/blender/blenkernel/intern/bpath.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c10
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c39
-rw-r--r--source/blender/blenkernel/intern/cachefile.c2
-rw-r--r--source/blender/blenkernel/intern/camera.c2
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/collection.c25
-rw-r--r--source/blender/blenkernel/intern/constraint.c2
-rw-r--r--source/blender/blenkernel/intern/context.c2
-rw-r--r--source/blender/blenkernel/intern/curve.c4
-rw-r--r--source/blender/blenkernel/intern/curve_deform.c2
-rw-r--r--source/blender/blenkernel/intern/customdata.c140
-rw-r--r--source/blender/blenkernel/intern/displist.c5
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c5
-rw-r--r--source/blender/blenkernel/intern/effect.c81
-rw-r--r--source/blender/blenkernel/intern/fcurve.c2
-rw-r--r--source/blender/blenkernel/intern/fluid.c2
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/geometry_set.cc114
-rw-r--r--source/blender/blenkernel/intern/gpencil.c189
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c44
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c9
-rw-r--r--source/blender/blenkernel/intern/hair.c2
-rw-r--r--source/blender/blenkernel/intern/icons.cc1
-rw-r--r--source/blender/blenkernel/intern/idprop.c104
-rw-r--r--source/blender/blenkernel/intern/image.c2
-rw-r--r--source/blender/blenkernel/intern/ipo.c2
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/lib_id.c29
-rw-r--r--source/blender/blenkernel/intern/lib_override.c472
-rw-r--r--source/blender/blenkernel/intern/lib_query.c12
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/light.c2
-rw-r--r--source/blender/blenkernel/intern/lightprobe.c2
-rw-r--r--source/blender/blenkernel/intern/linestyle.c2
-rw-r--r--source/blender/blenkernel/intern/main.c127
-rw-r--r--source/blender/blenkernel/intern/mask.c2
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c54
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c4
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/mball.c2
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c6
-rw-r--r--source/blender/blenkernel/intern/mesh_fair.cc2
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.cc2
-rw-r--r--source/blender/blenkernel/intern/movieclip.c2
-rw-r--r--source/blender/blenkernel/intern/multires.c2
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.c4
-rw-r--r--source/blender/blenkernel/intern/node.cc (renamed from source/blender/blenkernel/intern/node.c)771
-rw-r--r--source/blender/blenkernel/intern/object.c25
-rw-r--r--source/blender/blenkernel/intern/object_update.c2
-rw-r--r--source/blender/blenkernel/intern/ocean.c2
-rw-r--r--source/blender/blenkernel/intern/paint.c6
-rw-r--r--source/blender/blenkernel/intern/particle.c4
-rw-r--r--source/blender/blenkernel/intern/particle_system.c3
-rw-r--r--source/blender/blenkernel/intern/pointcloud.cc2
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c17
-rw-r--r--source/blender/blenkernel/intern/screen.c5
-rw-r--r--source/blender/blenkernel/intern/simulation.cc2
-rw-r--r--source/blender/blenkernel/intern/softbody.c5
-rw-r--r--source/blender/blenkernel/intern/sound.c2
-rw-r--r--source/blender/blenkernel/intern/speaker.c2
-rw-r--r--source/blender/blenkernel/intern/text.c2
-rw-r--r--source/blender/blenkernel/intern/texture.c2
-rw-r--r--source/blender/blenkernel/intern/tracking.c345
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c6
-rw-r--r--source/blender/blenkernel/intern/tracking_test.cc170
-rw-r--r--source/blender/blenkernel/intern/undo_system.c375
-rw-r--r--source/blender/blenkernel/intern/unit.c3
-rw-r--r--source/blender/blenkernel/intern/volume.cc34
-rw-r--r--source/blender/blenkernel/intern/volume_to_mesh.cc183
-rw-r--r--source/blender/blenkernel/intern/workspace.c2
-rw-r--r--source/blender/blenkernel/intern/world.c2
-rw-r--r--source/blender/blenkernel/nla_private.h17
-rw-r--r--source/blender/blenkernel/tracking_private.h2
-rw-r--r--source/blender/blenlib/BLI_fileops.h8
-rw-r--r--source/blender/blenlib/BLI_float2.hh13
-rw-r--r--source/blender/blenlib/BLI_fnmatch.h2
-rw-r--r--source/blender/blenlib/BLI_math.h3
-rw-r--r--source/blender/blenlib/BLI_math_base.h3
-rw-r--r--source/blender/blenlib/BLI_math_bits.h3
-rw-r--r--source/blender/blenlib/BLI_math_color.h3
-rw-r--r--source/blender/blenlib/BLI_math_color_blend.h3
-rw-r--r--source/blender/blenlib/BLI_math_geom.h8
-rw-r--r--source/blender/blenlib/BLI_math_inline.h3
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h2
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h5
-rw-r--r--source/blender/blenlib/BLI_math_solvers.h2
-rw-r--r--source/blender/blenlib/BLI_math_statistics.h2
-rw-r--r--source/blender/blenlib/BLI_math_vector.h3
-rw-r--r--source/blender/blenlib/BLI_mesh_intersect.hh4
-rw-r--r--source/blender/blenlib/BLI_mmap.h56
-rw-r--r--source/blender/blenlib/BLI_sys_types.h2
-rw-r--r--source/blender/blenlib/BLI_system.h2
-rw-r--r--source/blender/blenlib/BLI_task.hh6
-rw-r--r--source/blender/blenlib/BLI_voronoi_2d.h2
-rw-r--r--source/blender/blenlib/BLI_winstuff.h2
-rw-r--r--source/blender/blenlib/CMakeLists.txt2
-rw-r--r--source/blender/blenlib/intern/BLI_filelist.c2
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c10
-rw-r--r--source/blender/blenlib/intern/BLI_mmap.c237
-rw-r--r--source/blender/blenlib/intern/array_store.c2
-rw-r--r--source/blender/blenlib/intern/bitmap_draw_2d.c3
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c5
-rw-r--r--source/blender/blenlib/intern/convexhull_2d.c2
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.cc16
-rw-r--r--source/blender/blenlib/intern/dot_export.cc8
-rw-r--r--source/blender/blenlib/intern/freetypefont.c2
-rw-r--r--source/blender/blenlib/intern/gsqueue.c2
-rw-r--r--source/blender/blenlib/intern/jitter_2d.c2
-rw-r--r--source/blender/blenlib/intern/kdtree_impl.h2
-rw-r--r--source/blender/blenlib/intern/list_sort_impl.h2
-rw-r--r--source/blender/blenlib/intern/math_base.c3
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c7
-rw-r--r--source/blender/blenlib/intern/math_bits_inline.c3
-rw-r--r--source/blender/blenlib/intern/math_boolean.cc2
-rw-r--r--source/blender/blenlib/intern/math_color.c3
-rw-r--r--source/blender/blenlib/intern/math_color_blend_inline.c3
-rw-r--r--source/blender/blenlib/intern/math_color_inline.c5
-rw-r--r--source/blender/blenlib/intern/math_geom.c70
-rw-r--r--source/blender/blenlib/intern/math_geom_inline.c3
-rw-r--r--source/blender/blenlib/intern/math_interp.c8
-rw-r--r--source/blender/blenlib/intern/math_rotation.c4
-rw-r--r--source/blender/blenlib/intern/math_solvers.c2
-rw-r--r--source/blender/blenlib/intern/math_statistics.c2
-rw-r--r--source/blender/blenlib/intern/math_vec.cc2
-rw-r--r--source/blender/blenlib/intern/math_vector.c3
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c3
-rw-r--r--source/blender/blenlib/intern/mesh_boolean.cc349
-rw-r--r--source/blender/blenlib/intern/mesh_intersect.cc25
-rw-r--r--source/blender/blenlib/intern/path_util.c8
-rw-r--r--source/blender/blenlib/intern/polyfill_2d.c4
-rw-r--r--source/blender/blenlib/intern/scanfill.c6
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c2
-rw-r--r--source/blender/blenlib/intern/storage.c4
-rw-r--r--source/blender/blenlib/intern/string_search.cc2
-rw-r--r--source/blender/blenlib/intern/string_utf8.c3
-rw-r--r--source/blender/blenlib/intern/system.c2
-rw-r--r--source/blender/blenlib/intern/system_win32.c1
-rw-r--r--source/blender/blenlib/intern/task_graph.cc5
-rw-r--r--source/blender/blenlib/intern/task_pool.cc6
-rw-r--r--source/blender/blenlib/intern/task_range.cc7
-rw-r--r--source/blender/blenlib/intern/task_scheduler.cc6
-rw-r--r--source/blender/blenlib/intern/threads.cc7
-rw-r--r--source/blender/blenlib/intern/voxel.c8
-rw-r--r--source/blender/blenlib/tests/BLI_delaunay_2d_test.cc6
-rw-r--r--source/blender/blenlib/tests/BLI_polyfill_2d_test.cc18
-rw-r--r--source/blender/blenloader/BLO_readfile.h12
-rw-r--r--source/blender/blenloader/intern/blend_validate.c4
-rw-r--r--source/blender/blenloader/intern/readblenentry.c24
-rw-r--r--source/blender/blenloader/intern/readfile.c123
-rw-r--r--source/blender/blenloader/intern/readfile.h6
-rw-r--r--source/blender/blenloader/intern/versioning_260.c2
-rw-r--r--source/blender/blenloader/intern/versioning_270.c4
-rw-r--r--source/blender/blenloader/intern/versioning_280.c6
-rw-r--r--source/blender/blenloader/intern/versioning_290.c142
-rw-r--r--source/blender/blenloader/intern/versioning_cycles.c2
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c19
-rw-r--r--source/blender/blentranslation/intern/blt_lang.c26
-rw-r--r--source/blender/bmesh/bmesh_class.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_error.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c8
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c12
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c173
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c4
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c2
-rw-r--r--source/blender/bmesh/operators/bmo_fill_grid.c4
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c2
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c2
-rw-r--r--source/blender/bmesh/operators/bmo_normals.c2
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c6
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c2
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c6
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c37
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c7
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_edgenet.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c4
-rw-r--r--source/blender/compositor/COM_compositor.h6
-rw-r--r--source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp6
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.cpp2
-rw-r--r--source/blender/compositor/operations/COM_BokehImageOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_ChromaMatteOperation.cpp7
-rw-r--r--source/blender/compositor/operations/COM_CryptomatteOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_DotproductOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp3
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp3
-rw-r--r--source/blender/compositor/operations/COM_MixOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.cpp7
-rw-r--r--source/blender/datatoc/CMakeLists.txt2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc304
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc116
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc11
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc6
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc2
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc26
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.h4
-rw-r--r--source/blender/draw/engines/eevee/eevee_cryptomatte.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c16
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lut_gen.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h8
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_sampling.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows_cascade.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows_cube.c2
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl10
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl2
-rw-r--r--source/blender/draw/engines/external/external_engine.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c23
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h10
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_render.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c10
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl2
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl2
-rw-r--r--source/blender/draw/engines/image/image_shader.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_antialiasing.c6
-rw-r--r--source/blender/draw/engines/overlay/overlay_armature.c4
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_mesh.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_uv.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_extra.c8
-rw-r--r--source/blender/draw/engines/overlay/overlay_gpencil.c15
-rw-r--r--source/blender/draw/engines/overlay/overlay_metaball.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_particle.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.c2
-rw-r--r--source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/extra_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/extra_wire_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_antialiasing.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h4
-rw-r--r--source/blender/draw/engines/workbench/workbench_shader.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_shadow.c2
-rw-r--r--source/blender/draw/intern/DRW_render.h6
-rw-r--r--source/blender/draw/intern/draw_cache.c6
-rw-r--r--source/blender/draw/intern/draw_cache.h2
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c6
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c2
-rw-r--r--source/blender/draw/intern/draw_cache_impl_gpencil.c8
-rw-r--r--source/blender/draw/intern/draw_cache_impl_hair.c2
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c2
-rw-r--r--source/blender/draw/intern/draw_common.c4
-rw-r--r--source/blender/draw/intern/draw_hair.c2
-rw-r--r--source/blender/draw/intern/draw_manager.c42
-rw-r--r--source/blender/draw/intern/draw_manager.h8
-rw-r--r--source/blender/draw/intern/draw_manager_data.c6
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c6
-rw-r--r--source/blender/draw/intern/draw_manager_texture.c2
-rw-r--r--source/blender/draw/intern/shaders/common_fxaa_lib.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_smaa_lib.glsl2
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c67
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c10
-rw-r--r--source/blender/editors/animation/anim_filter.c7
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c2
-rw-r--r--source/blender/editors/animation/anim_ops.c4
-rw-r--r--source/blender/editors/animation/drivers.c1
-rw-r--r--source/blender/editors/animation/keyframes_draw.c96
-rw-r--r--source/blender/editors/animation/keyframes_general.c2
-rw-r--r--source/blender/editors/animation/keyframing.c4
-rw-r--r--source/blender/editors/animation/time_scrub_ui.c33
-rw-r--r--source/blender/editors/armature/armature_add.c6
-rw-r--r--source/blender/editors/armature/armature_ops.c2
-rw-r--r--source/blender/editors/armature/armature_skinning.c3
-rw-r--r--source/blender/editors/armature/armature_utils.c4
-rw-r--r--source/blender/editors/armature/editarmature_undo.c7
-rw-r--r--source/blender/editors/armature/meshlaplacian.c4
-rw-r--r--source/blender/editors/armature/pose_edit.c2
-rw-r--r--source/blender/editors/armature/pose_group.c2
-rw-r--r--source/blender/editors/armature/pose_lib.c4
-rw-r--r--source/blender/editors/armature/pose_slide.c28
-rw-r--r--source/blender/editors/armature/pose_transform.c2
-rw-r--r--source/blender/editors/armature/pose_utils.c3
-rw-r--r--source/blender/editors/asset/CMakeLists.txt4
-rw-r--r--source/blender/editors/asset/asset_edit.cc (renamed from source/blender/editors/asset/asset_edit.c)6
-rw-r--r--source/blender/editors/asset/asset_ops.c247
-rw-r--r--source/blender/editors/asset/asset_ops.cc259
-rw-r--r--source/blender/editors/curve/editcurve.c8
-rw-r--r--source/blender/editors/curve/editcurve_select.c2
-rw-r--r--source/blender/editors/curve/editcurve_undo.c7
-rw-r--r--source/blender/editors/curve/editfont_undo.c7
-rw-r--r--source/blender/editors/geometry/geometry_attributes.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_presets.c7
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c3
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c11
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c11
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_add_monkey.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_add_stroke.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_armature.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c39
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c139
-rw-r--r--source/blender/editors/gpencil/gpencil_edit_curve.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c1142
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h16
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c25
-rw-r--r--source/blender/editors/gpencil/gpencil_merge.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_ops_versioning.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c92
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c22
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_trace_ops.c25
-rw-r--r--source/blender/editors/gpencil/gpencil_undo.c23
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c81
-rw-r--r--source/blender/editors/gpencil/gpencil_uv.c1
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_ops.c14
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c27
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c25
-rw-r--r--source/blender/editors/include/ED_clip.h24
-rw-r--r--source/blender/editors/include/ED_fileselect.h2
-rw-r--r--source/blender/editors/include/ED_gpencil.h17
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h2
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h2
-rw-r--r--source/blender/editors/include/ED_mask.h5
-rw-r--r--source/blender/editors/include/ED_node.h4
-rw-r--r--source/blender/editors/include/ED_object.h2
-rw-r--r--source/blender/editors/include/ED_screen.h44
-rw-r--r--source/blender/editors/include/ED_transform.h24
-rw-r--r--source/blender/editors/include/UI_interface.h78
-rw-r--r--source/blender/editors/include/UI_interface_icons.h5
-rw-r--r--source/blender/editors/include/UI_resources.h2
-rw-r--r--source/blender/editors/include/UI_view2d.h2
-rw-r--r--source/blender/editors/interface/interface.c16
-rw-r--r--source/blender/editors/interface/interface_context_menu.c2
-rw-r--r--source/blender/editors/interface/interface_draw.c734
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface_eyedropper_depth.c6
-rw-r--r--source/blender/editors/interface/interface_handlers.c83
-rw-r--r--source/blender/editors/interface/interface_icons_event.c10
-rw-r--r--source/blender/editors/interface/interface_intern.h6
-rw-r--r--source/blender/editors/interface/interface_layout.c4
-rw-r--r--source/blender/editors/interface/interface_ops.c2
-rw-r--r--source/blender/editors/interface/interface_panel.c92
-rw-r--r--source/blender/editors/interface/interface_region_menu_pie.c2
-rw-r--r--source/blender/editors/interface/interface_region_popup.c11
-rw-r--r--source/blender/editors/interface/interface_region_search.c26
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c80
-rw-r--r--source/blender/editors/interface/interface_style.c17
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.c1
-rw-r--r--source/blender/editors/interface/interface_template_search_operator.c3
-rw-r--r--source/blender/editors/interface/interface_templates.c108
-rw-r--r--source/blender/editors/interface/interface_utils.c67
-rw-r--r--source/blender/editors/interface/interface_widgets.c44
-rw-r--r--source/blender/editors/interface/view2d.c2
-rw-r--r--source/blender/editors/interface/view2d_ops.c122
-rw-r--r--source/blender/editors/io/io_alembic.c3
-rw-r--r--source/blender/editors/io/io_cache.c1
-rw-r--r--source/blender/editors/io/io_collada.c2
-rw-r--r--source/blender/editors/lattice/editlattice_select.c2
-rw-r--r--source/blender/editors/lattice/editlattice_undo.c7
-rw-r--r--source/blender/editors/lattice/lattice_ops.c5
-rw-r--r--source/blender/editors/mask/mask_add.c10
-rw-r--r--source/blender/editors/mask/mask_draw.c4
-rw-r--r--source/blender/editors/mask/mask_edit.c36
-rw-r--r--source/blender/editors/mask/mask_intern.h15
-rw-r--r--source/blender/editors/mask/mask_ops.c47
-rw-r--r--source/blender/editors/mask/mask_query.c42
-rw-r--r--source/blender/editors/mask/mask_select.c13
-rw-r--r--source/blender/editors/mesh/editmesh_add.c2
-rw-r--r--source/blender/editors/mesh/editmesh_automerge.c3
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c4
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c7
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c6
-rw-r--r--source/blender/editors/mesh/editmesh_select.c6
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c4
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c9
-rw-r--r--source/blender/editors/mesh/mesh_ops.c3
-rw-r--r--source/blender/editors/mesh/meshtools.c4
-rw-r--r--source/blender/editors/metaball/editmball_undo.c7
-rw-r--r--source/blender/editors/metaball/mball_edit.c2
-rw-r--r--source/blender/editors/metaball/mball_ops.c2
-rw-r--r--source/blender/editors/object/object_add.c11
-rw-r--r--source/blender/editors/object/object_bake_api.c2
-rw-r--r--source/blender/editors/object/object_data_transfer.c4
-rw-r--r--source/blender/editors/object/object_modifier.c2
-rw-r--r--source/blender/editors/object/object_ops.c8
-rw-r--r--source/blender/editors/object/object_relations.c35
-rw-r--r--source/blender/editors/object/object_remesh.c6
-rw-r--r--source/blender/editors/object/object_select.c4
-rw-r--r--source/blender/editors/object/object_shapekey.c2
-rw-r--r--source/blender/editors/object/object_transform.c2
-rw-r--r--source/blender/editors/object/object_volume.c3
-rw-r--r--source/blender/editors/object/object_warp.c9
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c2
-rw-r--r--source/blender/editors/physics/particle_boids.c1
-rw-r--r--source/blender/editors/physics/particle_edit.c13
-rw-r--r--source/blender/editors/physics/particle_edit_undo.c2
-rw-r--r--source/blender/editors/physics/physics_fluid.c6
-rw-r--r--source/blender/editors/physics/physics_ops.c5
-rw-r--r--source/blender/editors/physics/physics_pointcache.c1
-rw-r--r--source/blender/editors/physics/rigidbody_object.c2
-rw-r--r--source/blender/editors/render/render_internal.c12
-rw-r--r--source/blender/editors/render/render_opengl.c2
-rw-r--r--source/blender/editors/render/render_preview.c23
-rw-r--r--source/blender/editors/render/render_update.c6
-rw-r--r--source/blender/editors/screen/area.c93
-rw-r--r--source/blender/editors/screen/area_utils.c14
-rw-r--r--source/blender/editors/screen/glutil.c20
-rw-r--r--source/blender/editors/screen/screen_context.c2
-rw-r--r--source/blender/editors/screen/screen_draw.c2
-rw-r--r--source/blender/editors/screen/screen_edit.c9
-rw-r--r--source/blender/editors/screen/screen_intern.h8
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve_undo.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c62
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c11
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c2713
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_automasking.c24
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c309
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c283
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_detail.c17
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c168
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c170
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c218
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c78
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c162
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c13
-rw-r--r--source/blender/editors/sound/sound_ops.c3
-rw-r--r--source/blender/editors/space_action/action_buttons.c23
-rw-r--r--source/blender/editors/space_action/action_edit.c6
-rw-r--r--source/blender/editors/space_action/action_ops.c3
-rw-r--r--source/blender/editors/space_action/space_action.c73
-rw-r--r--source/blender/editors/space_api/spacetypes.c72
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c3
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c3
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c40
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c1
-rw-r--r--source/blender/editors/space_clip/clip_editor.c160
-rw-r--r--source/blender/editors/space_clip/clip_intern.h8
-rw-r--r--source/blender/editors/space_clip/clip_ops.c18
-rw-r--r--source/blender/editors/space_clip/clip_toolbar.c12
-rw-r--r--source/blender/editors/space_clip/clip_utils.c227
-rw-r--r--source/blender/editors/space_clip/space_clip.c67
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c114
-rw-r--r--source/blender/editors/space_clip/tracking_ops_detect.c4
-rw-r--r--source/blender/editors/space_clip/tracking_ops_stabilize.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops_track.c1
-rw-r--r--source/blender/editors/space_clip/tracking_ops_utils.c4
-rw-r--r--source/blender/editors/space_clip/tracking_select.c18
-rw-r--r--source/blender/editors/space_console/console_ops.c4
-rw-r--r--source/blender/editors/space_console/space_console.c13
-rw-r--r--source/blender/editors/space_file/file_draw.c14
-rw-r--r--source/blender/editors/space_file/file_utils.c1
-rw-r--r--source/blender/editors/space_file/filelist.c17
-rw-r--r--source/blender/editors/space_file/filesel.c2
-rw-r--r--source/blender/editors/space_file/space_file.c97
-rw-r--r--source/blender/editors/space_graph/graph_edit.c4
-rw-r--r--source/blender/editors/space_graph/graph_ops.c4
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c20
-rw-r--r--source/blender/editors/space_graph/graph_utils.c2
-rw-r--r--source/blender/editors/space_graph/space_graph.c30
-rw-r--r--source/blender/editors/space_image/image_draw.c4
-rw-r--r--source/blender/editors/space_image/image_intern.h1
-rw-r--r--source/blender/editors/space_image/image_ops.c139
-rw-r--r--source/blender/editors/space_image/image_sequence.c4
-rw-r--r--source/blender/editors/space_image/image_undo.c8
-rw-r--r--source/blender/editors/space_image/space_image.c57
-rw-r--r--source/blender/editors/space_info/info_draw.c47
-rw-r--r--source/blender/editors/space_info/info_ops.c13
-rw-r--r--source/blender/editors/space_info/space_info.c36
-rw-r--r--source/blender/editors/space_info/textview.c17
-rw-r--r--source/blender/editors/space_nla/nla_draw.c26
-rw-r--r--source/blender/editors/space_nla/nla_edit.c11
-rw-r--r--source/blender/editors/space_nla/nla_ops.c5
-rw-r--r--source/blender/editors/space_nla/space_nla.c64
-rw-r--r--source/blender/editors/space_node/drawnode.c328
-rw-r--r--source/blender/editors/space_node/node_add.c30
-rw-r--r--source/blender/editors/space_node/node_buttons.c1
-rw-r--r--source/blender/editors/space_node/node_draw.c284
-rw-r--r--source/blender/editors/space_node/node_edit.c53
-rw-r--r--source/blender/editors/space_node/node_group.c2
-rw-r--r--source/blender/editors/space_node/node_intern.h54
-rw-r--r--source/blender/editors/space_node/node_ops.c4
-rw-r--r--source/blender/editors/space_node/node_relationships.c270
-rw-r--r--source/blender/editors/space_node/node_select.c6
-rw-r--r--source/blender/editors/space_node/node_templates.c1
-rw-r--r--source/blender/editors/space_node/node_toolbar.c3
-rw-r--r--source/blender/editors/space_node/node_view.c1
-rw-r--r--source/blender/editors/space_node/space_node.c70
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_outliner/outliner_context.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c59
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c13
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c23
-rw-r--r--source/blender/editors/space_outliner/outliner_sync.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c49
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c280
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c35
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.cc2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.cc2
-rw-r--r--source/blender/editors/space_script/space_script.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c5
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c21
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c5
-rw-r--r--source/blender/editors/space_sequencer/sequencer_proxy.c1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c119
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c50
-rw-r--r--source/blender/editors/space_statusbar/space_statusbar.c21
-rw-r--r--source/blender/editors/space_text/space_text.c9
-rw-r--r--source/blender/editors/space_text/text_draw.c28
-rw-r--r--source/blender/editors/space_text/text_format.c2
-rw-r--r--source/blender/editors/space_text/text_ops.c2
-rw-r--r--source/blender/editors/space_text/text_undo.c11
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c31
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c34
-rw-r--r--source/blender/editors/space_userpref/userpref_ops.c4
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c103
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c35
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_forcefield.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate.c27
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c620
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c42
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c4
-rw-r--r--source/blender/editors/transform/CMakeLists.txt1
-rw-r--r--source/blender/editors/transform/transform.c34
-rw-r--r--source/blender/editors/transform/transform.h460
-rw-r--r--source/blender/editors/transform/transform_constraints.c143
-rw-r--r--source/blender/editors/transform/transform_convert.c425
-rw-r--r--source/blender/editors/transform/transform_convert.h35
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c6
-rw-r--r--source/blender/editors/transform/transform_convert_curve.c2
-rw-r--r--source/blender/editors/transform/transform_convert_gpencil.c12
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c221
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_skin.c4
-rw-r--r--source/blender/editors/transform/transform_convert_nla.c34
-rw-r--r--source/blender/editors/transform/transform_convert_object.c72
-rw-r--r--source/blender/editors/transform/transform_convert_object_texspace.c126
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c28
-rw-r--r--source/blender/editors/transform/transform_convert_tracking.c246
-rw-r--r--source/blender/editors/transform/transform_data.h10
-rw-r--r--source/blender/editors/transform/transform_draw_cursors.c396
-rw-r--r--source/blender/editors/transform/transform_generics.c137
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c4
-rw-r--r--source/blender/editors/transform/transform_input.c24
-rw-r--r--source/blender/editors/transform/transform_mode.c14
-rw-r--r--source/blender/editors/transform/transform_mode_align.c2
-rw-r--r--source/blender/editors/transform/transform_mode_edge_seq_slide.c11
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c2
-rw-r--r--source/blender/editors/transform/transform_mode_mirror.c2
-rw-r--r--source/blender/editors/transform/transform_mode_resize.c2
-rw-r--r--source/blender/editors/transform/transform_mode_shrink_fatten.c17
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c2
-rw-r--r--source/blender/editors/transform/transform_ops.c6
-rw-r--r--source/blender/editors/transform/transform_orientations.c30
-rw-r--r--source/blender/editors/transform/transform_snap.c245
-rw-r--r--source/blender/editors/transform/transform_snap_object.c2
-rw-r--r--source/blender/editors/undo/ed_undo.c222
-rw-r--r--source/blender/editors/undo/memfile_undo.c18
-rw-r--r--source/blender/editors/util/CMakeLists.txt2
-rw-r--r--source/blender/editors/util/ed_transverts.c4
-rw-r--r--source/blender/editors/util/ed_util.c2
-rw-r--r--source/blender/editors/util/ed_util_ops.cc (renamed from source/blender/editors/util/ed_util_ops.c)28
-rw-r--r--source/blender/editors/util/numinput.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c14
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c12
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c6
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp2
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp13
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h4
-rw-r--r--source/blender/freestyle/intern/geometry/GeomUtils.cpp4
-rw-r--r--source/blender/freestyle/intern/geometry/matrix_util.cpp2
-rw-r--r--source/blender/freestyle/intern/geometry/matrix_util.h2
-rw-r--r--source/blender/freestyle/intern/geometry/normal_cycle.cpp2
-rw-r--r--source/blender/freestyle/intern/geometry/normal_cycle.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_BBox.cpp3
-rw-r--r--source/blender/freestyle/intern/python/BPy_BBox.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.cpp3
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.h128
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsMaterial.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsNoise.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsNoise.h6
-rw-r--r--source/blender/freestyle/intern/python/BPy_Id.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Id.h6
-rw-r--r--source/blender/freestyle/intern/python/BPy_IntegrationType.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_IntegrationType.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface0D.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface1D.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_Iterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Iterator.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_MediumType.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_MediumType.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Nature.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Nature.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.cpp6
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_SShape.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_SShape.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeAttribute.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeShader.h6
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewMap.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewMap.h4
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewShape.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewShape.h4
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Director.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Director.h33
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h3
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h3
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h3
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h3
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.h6
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.cpp2
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.h2
-rw-r--r--source/blender/functions/FN_cpp_type.hh5
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c36
-rw-r--r--source/blender/gpu/GPU_batch.h4
-rw-r--r--source/blender/gpu/GPU_framebuffer.h6
-rw-r--r--source/blender/gpu/GPU_index_buffer.h2
-rw-r--r--source/blender/gpu/GPU_platform.h1
-rw-r--r--source/blender/gpu/GPU_shader.h2
-rw-r--r--source/blender/gpu/GPU_state.h4
-rw-r--r--source/blender/gpu/GPU_texture.h6
-rw-r--r--source/blender/gpu/GPU_vertex_buffer.h2
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c2
-rw-r--r--source/blender/gpu/intern/gpu_context_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_drawlist_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc2
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer_private.hh9
-rw-r--r--source/blender/gpu/intern/gpu_immediate_private.hh8
-rw-r--r--source/blender/gpu/intern/gpu_index_buffer_private.hh4
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c2
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c2
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc2
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh4
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_state.cc5
-rw-r--r--source/blender/gpu/intern/gpu_state_private.hh6
-rw-r--r--source/blender/gpu/intern/gpu_texture_private.hh8
-rw-r--r--source/blender/gpu/intern/gpu_uniform_buffer_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer_private.hh4
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc8
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c10
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc28
-rw-r--r--source/blender/gpu/opengl/gl_batch.hh4
-rw-r--r--source/blender/gpu/opengl/gl_context.cc4
-rw-r--r--source/blender/gpu/opengl/gl_context.hh8
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc2
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.cc6
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.hh12
-rw-r--r--source/blender/gpu/opengl/gl_primitive.hh2
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc6
-rw-r--r--source/blender/gpu/opengl/gl_state.hh2
-rw-r--r--source/blender/gpu/opengl/gl_texture.cc2
-rw-r--r--source/blender/gpu/opengl/gl_texture.hh8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl2
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp2
-rw-r--r--source/blender/imbuf/IMB_metadata.h2
-rw-r--r--source/blender/imbuf/intern/IMB_allocimbuf.h2
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c4
-rw-r--r--source/blender/imbuf/intern/anim_movie.c6
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.cpp2
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h2
-rw-r--r--source/blender/imbuf/intern/filter.c2
-rw-r--r--source/blender/imbuf/intern/imageprocess.c2
-rw-r--r--source/blender/imbuf/intern/jp2.c6
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp4
-rw-r--r--source/blender/imbuf/intern/readimage.c24
-rw-r--r--source/blender/imbuf/intern/targa.c2
-rw-r--r--source/blender/imbuf/intern/thumbs.c2
-rw-r--r--source/blender/imbuf/intern/thumbs_blend.c2
-rw-r--r--source/blender/imbuf/intern/tiff.c4
-rw-r--r--source/blender/io/alembic/exporter/abc_archive.cc2
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.h2
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_transform.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_util.cc2
-rw-r--r--source/blender/io/collada/AnimationImporter.cpp4
-rw-r--r--source/blender/io/collada/ArmatureExporter.cpp4
-rw-r--r--source/blender/io/collada/ArmatureImporter.cpp2
-rw-r--r--source/blender/io/collada/BCAnimationCurve.h2
-rw-r--r--source/blender/io/collada/BCAnimationSampler.cpp2
-rw-r--r--source/blender/io/collada/DocumentImporter.cpp12
-rw-r--r--source/blender/io/collada/DocumentImporter.h2
-rw-r--r--source/blender/io/collada/MeshImporter.cpp2
-rw-r--r--source/blender/io/common/IO_dupli_persistent_id.hh2
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator.cc2
-rw-r--r--source/blender/io/common/intern/object_identifier_test.cc2
-rw-r--r--source/blender/io/usd/CMakeLists.txt3
-rw-r--r--source/blender/makesdna/DNA_ID.h101
-rw-r--r--source/blender/makesdna/DNA_ID_enums.h118
-rw-r--r--source/blender/makesdna/DNA_action_types.h2
-rw-r--r--source/blender/makesdna/DNA_anim_types.h5
-rw-r--r--source/blender/makesdna/DNA_brush_enums.h4
-rw-r--r--source/blender/makesdna/DNA_brush_types.h13
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h2
-rw-r--r--source/blender/makesdna/DNA_dynamicpaint_types.h6
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_defaults.h1
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h4
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h19
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h5
-rw-r--r--source/blender/makesdna/DNA_modifier_defaults.h6
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h6
-rw-r--r--source/blender/makesdna/DNA_node_types.h103
-rw-r--r--source/blender/makesdna/DNA_outliner_types.h96
-rw-r--r--source/blender/makesdna/DNA_space_types.h38
-rw-r--r--source/blender/makesdna/DNA_tracking_types.h12
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h13
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h2
-rw-r--r--source/blender/makesdna/intern/CMakeLists.txt6
-rw-r--r--source/blender/makesdna/intern/makesdna.c19
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt1
-rw-r--r--source/blender/makesrna/intern/makesrna.c11
-rw-r--r--source/blender/makesrna/intern/rna_access.c6
-rw-r--r--source/blender/makesrna/intern/rna_access_compare_override.c14
-rw-r--r--source/blender/makesrna/intern/rna_animviz.c2
-rw-r--r--source/blender/makesrna/intern/rna_attribute.c35
-rw-r--r--source/blender/makesrna/intern/rna_brush.c37
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c2
-rw-r--r--source/blender/makesrna/intern/rna_define.c12
-rw-r--r--source/blender/makesrna/intern/rna_depsgraph.c4
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c2
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c2
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c202
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c9
-rw-r--r--source/blender/makesrna/intern/rna_lattice.c4
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c4
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c58
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c237
-rw-r--r--source/blender/makesrna/intern/rna_object.c24
-rw-r--r--source/blender/makesrna/intern/rna_render.c8
-rw-r--r--source/blender/makesrna/intern/rna_rna.c54
-rw-r--r--source/blender/makesrna/intern/rna_scene.c6
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c2
-rw-r--r--source/blender/makesrna/intern/rna_space.c44
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c16
-rw-r--r--source/blender/makesrna/intern/rna_ui.c6
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c30
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c24
-rw-r--r--source/blender/makesrna/intern/rna_vfont.c2
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c10
-rw-r--r--source/blender/makesrna/intern/rna_wm_gizmo.c4
-rw-r--r--source/blender/modifiers/CMakeLists.txt2
-rw-r--r--source/blender/modifiers/intern/MOD_array.c3
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c2
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c4
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc101
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c6
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c4
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_nonmanifold.c4
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c159
-rw-r--r--source/blender/modifiers/intern/MOD_volume_to_mesh.cc165
-rw-r--r--source/blender/nodes/CMakeLists.txt20
-rw-r--r--source/blender/nodes/NOD_derived_node_tree.hh7
-rw-r--r--source/blender/nodes/NOD_function.h6
-rw-r--r--source/blender/nodes/NOD_geometry.h34
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh35
-rw-r--r--source/blender/nodes/NOD_static_types.h8
-rw-r--r--source/blender/nodes/function/nodes/node_fn_boolean_math.cc9
-rw-r--r--source/blender/nodes/function/nodes/node_fn_float_compare.cc9
-rw-r--r--source/blender/nodes/function/nodes/node_fn_input_vector.cc11
-rw-r--r--source/blender/nodes/function/nodes/node_fn_switch.cc10
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc120
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc11
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc135
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc15
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc198
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_proximity.cc235
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc31
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc118
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc148
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc61
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_boolean.cc9
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_collection_info.cc108
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc47
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc48
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_object_info.cc22
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc201
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_instance.cc41
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_rotate.cc21
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_scale.cc9
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_translate.cc9
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc273
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc15
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc50
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_triangulate.cc10
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc171
-rw-r--r--source/blender/nodes/intern/derived_node_tree.cc2
-rw-r--r--source/blender/nodes/intern/node_tree_multi_function.cc58
-rw-r--r--source/blender/nodes/intern/node_util.c26
-rw-r--r--source/blender/nodes/texture/node_texture_util.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c54
-rw-r--r--source/blender/python/generic/py_capi_utils.c6
-rw-r--r--source/blender/python/generic/py_capi_utils.h2
-rw-r--r--source/blender/python/gpu/gpu_py_shader.c19
-rw-r--r--source/blender/python/intern/bpy_app.c5
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c20
-rw-r--r--source/blender/python/intern/bpy_interface_atexit.c2
-rw-r--r--source/blender/python/intern/bpy_library_load.c32
-rw-r--r--source/blender/python/intern/bpy_rna.c16
-rw-r--r--source/blender/render/RE_engine.h1
-rw-r--r--source/blender/render/RE_multires_bake.h2
-rw-r--r--source/blender/render/RE_pipeline.h4
-rw-r--r--source/blender/render/intern/initrender.c42
-rw-r--r--source/blender/render/intern/multires_bake.c2
-rw-r--r--source/blender/render/intern/pipeline.c80
-rw-r--r--source/blender/render/intern/render_result.c2
-rw-r--r--source/blender/render/intern/render_types.h2
-rw-r--r--source/blender/render/intern/texture_image.c2
-rw-r--r--source/blender/render/intern/texture_procedural.c6
-rw-r--r--source/blender/render/intern/zbuf.c2
-rw-r--r--source/blender/sequencer/SEQ_render.h2
-rw-r--r--source/blender/sequencer/SEQ_select.h4
-rw-r--r--source/blender/sequencer/intern/image_cache.c182
-rw-r--r--source/blender/sequencer/intern/image_cache.h9
-rw-r--r--source/blender/sequencer/intern/iterator.c20
-rw-r--r--source/blender/sequencer/intern/prefetch.c8
-rw-r--r--source/blender/sequencer/intern/render.c36
-rw-r--r--source/blender/sequencer/intern/strip_select.c16
-rw-r--r--source/blender/simulation/intern/implicit_blender.c4
-rw-r--r--source/blender/simulation/intern/implicit_eigen.cpp4
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/WM_keymap.h10
-rw-r--r--source/blender/windowmanager/gizmo/WM_gizmo_api.h2
-rw-r--r--source/blender/windowmanager/gizmo/WM_gizmo_types.h8
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c2
-rw-r--r--source/blender/windowmanager/gizmo/wm_gizmo_fn.h3
-rw-r--r--source/blender/windowmanager/intern/wm.c2
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c3
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c11
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c34
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c21
-rw-r--r--source/blender/windowmanager/intern/wm_keymap_utils.c6
-rw-r--r--source/blender/windowmanager/intern/wm_operator_props.c18
-rw-r--r--source/blender/windowmanager/intern/wm_operator_type.c5
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c2
-rw-r--r--source/blender/windowmanager/intern/wm_window.c48
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_draw.c2
-rw-r--r--source/creator/CMakeLists.txt5
-rw-r--r--source/creator/creator_args.c22
-rw-r--r--tests/gtests/runner/CMakeLists.txt25
1341 files changed, 24391 insertions, 14625 deletions
diff --git a/.clang-tidy b/.clang-tidy
index d65027687bb..b51555b55dd 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -39,9 +39,8 @@ Checks: >
-modernize-use-nodiscard,
-modernize-loop-convert,
-modernize-pass-by-value,
- -modernize-use-default-member-init,
- -modernize-raw-string-literal,
- -modernize-avoid-bind,
- -modernize-use-transparent-functors,
WarningsAsErrors: '*'
+CheckOptions:
+ - key: modernize-use-default-member-init.UseAssignment
+ value: 1
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index d864e08c953..0cad9be4693 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -10,8 +10,9 @@
# Changes that belong here:
# - Massive comment, doxy-sections, or spelling corrections.
# - Clang-format, PEP8 or other automated changes which are *strictly* "no functional change".
-# - Several smaller commits should be added to this list at once, because adding
-# one extra commit (to edit this file) after every small cleanup is noisy.
+# - Several commits should be added to this list at once, because adding
+# one extra commit (to edit this file) after every cleanup is noisy.
+# - No clang-tidy changes.
#
# Note:
# - The comment above the SHA should be the first line of the commit.
@@ -92,78 +93,12 @@ c42a6b77b52560d257279de2cb624b4ef2c0d24c
# Cleanup: use doxy sections for imbuf
c207f7c22e1439e0b285fba5d2c072bdae23f981
-# Cleanup: Clang-Tidy, modernize-use-bool-literals
-af35ada2f3fa8da4d46b3a71de724d353d716820
-
-# Cleanup: Use nullptr everywhere in fluid code
-311031ecd03dbfbf43e1df672a395f24b2e7d4d3
-
-# Cleanup: Clang-Tidy, modernize-redundant-void-arg
-a331d5c99299c4514ca33c843b1c79b872f2728d
-
-# Cleanup: Clang-Tidy modernize-use-nullptr
-16732def37c5a66f3ea28dbe247b09cc6bca6677
-
-# Cleanup: Clang-tidy, modernize-concat-nested-namespaces
-4525049aa0cf818f6483dce589ac9791eb562338
-
-# Cleanup: Clang-tidy else-after-return
-ae342ed4511cf2e144dcd27ce2c635d3d536f9ad
-
-# Cleanup: Clang-Tidy, readability-redundant-member-init
-190170d4cc92ff34abe1744a10474ac4f1074086
-
-# Cleanup: use 'filepath' instead of 'name' for ImBuf utilities
-99f56b4c16323f96c0cbf54e392fb509fcac5bda
-
# Cleanup: clang-format
c4d8f6a4a8ddc29ed27311ed7578b3c8c31399d2
b5d310b569e07a937798a2d38539cfd290149f1c
8c846cccd6bdfd3e90a695fabbf05f53e5466a57
-40d4a4cb1a6b4c3c2a486e8f2868f547530e0811
4eac03d821fa17546f562485f7d073813a5e5943
+1166110a9d66af9c5a47cee2be591f50fdc445e8
-# Cleanup: use preprocessor version check for PyTypeObject declaration
-cd9acfed4f7674b84be965d469a367aef96f8af3
-
-# Cycles: fix compilation of OSL shaders following API change
-b980cd163a9d5d77eeffc2e353333e739fa9e719
-
-# Cleanup: clang-tidy suppress warnings for PyTypeObject.tp_print
-efd71aad4f22ec0073d80b8dd296015d3f395aa8
-
-# Cleanup: fix wrong merge, remove extra unique_ptr.
-6507449e54a167c63a72229e4d0119dd2af68ae5
-
-# Cleanup: fix some clang tidy issues
-525a042c5c7513c41240b118acca002f6c60cc12
-
-# Fix T82520: error building freestyle with Python3.8
-e118426e4695a97d67e65d69677f3c4e2db50a56
-
-# Cleanup: Clang-tidy, readability-else-after-return
-7be47dadea5066ae095c644e0b4f1f10d75f5ab3
-
-# Cleanup: Add `r_` to return parameter
-45dca05b1cd2a5ead59144c93d790fdfe7c35ee6
-
-# Cleanup: Typo in `print_default_info` function name.
-41a73909dec716642f044e60b40a28335c9fdb10
-
-# Cleanup: Reduce indentation
-1cc3a0e2cf73a5ff4f9e0a7f5338eda77266b300
-
-# Build-system: Force C linkage for all DNA type headers
-ad4b7741dba45a2be210942c18af6b6e4438f129
-
-# Cleanup: Move function to proper section
-c126e27cdc8b28365a9d5f9fafc4d521d1eb83df
-
-# Cleanup: remove break after return statements
-bbdfeb751e16d939482d2e4b95c4d470f53f18a5
-
-# Cleanup: clang-tidy
-af013ff76feef7e8b8ba642279c62a5dc275d59f
-
-# Cleanup: Make panel type flag names more clear
-9d28353b525ecfbcca1501be72e4276dfb2bbc2a
+# Cleanup: clang-format.
+40d4a4cb1a6b4c3c2a486e8f2868f547530e0811
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 035cf81e1b3..78f49942a13 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,6 +63,9 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build_files/cmake/platform")
# avoid having empty buildtype
if(NOT DEFINED CMAKE_BUILD_TYPE_INIT)
set(CMAKE_BUILD_TYPE_INIT "Release")
+ # Internal logic caches this variable, avoid showing it by default
+ # since it's easy to accidentally set instead of the build type.
+ mark_as_advanced(CMAKE_BUILD_TYPE_INIT)
endif()
# Omit superfluous "Up-to-date" messages.
@@ -164,10 +167,6 @@ if(APPLE)
endif()
option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ON)
-if(${CMAKE_VERSION} VERSION_LESS 2.8.8)
- # add_library OBJECT arg unsupported
- set(WITH_BUILDINFO OFF)
-endif()
set(BUILDINFO_OVERRIDE_DATE "" CACHE STRING "Use instead of the current date for reproducible builds (empty string disables this option)")
set(BUILDINFO_OVERRIDE_TIME "" CACHE STRING "Use instead of the current time for reproducible builds (empty string disables this option)")
set(CPACK_OVERRIDE_PACKAGENAME "" CACHE STRING "Use instead of the standard packagename (empty string disables this option)")
@@ -205,6 +204,7 @@ option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if
option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF)
mark_as_advanced(WITH_OPENVDB_3_ABI_COMPATIBLE)
option(WITH_NANOVDB "Enable usage of NanoVDB data structure for rendering on the GPU" ON)
+option(WITH_HARU "Enable features relying on Libharu (Grease pencil PDF export)" ON)
# GHOST Windowing Library Options
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
@@ -613,6 +613,7 @@ endif()
if(UNIX)
# See WITH_WINDOWS_SCCACHE for Windows.
option(WITH_COMPILER_CCACHE "Use ccache to improve rebuild times (Works with Ninja, Makefiles and Xcode)" OFF)
+ mark_as_advanced(WITH_COMPILER_CCACHE)
endif()
# The following only works with the Ninja generator in CMake >= 3.0.
@@ -730,6 +731,9 @@ set_and_warn_dependency(WITH_OPENVDB WITH_NANOVDB OFF)
# OpenVDB uses 'half' type from OpenEXR & fails to link without OpenEXR enabled.
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF)
+# Haru needs `TIFFFaxBlackCodes` & `TIFFFaxWhiteCodes` symbols from TIFF.
+set_and_warn_dependency(WITH_IMAGE_TIFF WITH_HARU OFF)
+
# auto enable openimageio for cycles
if(WITH_CYCLES)
set(WITH_OPENIMAGEIO ON)
@@ -1018,6 +1022,9 @@ if(WITH_OPENVDB)
list(APPEND OPENVDB_DEFINITIONS -DOPENVDB_3_ABI_COMPATIBLE)
endif()
+ # OpenVDB headers use deprecated TBB headers, silence warning.
+ list(APPEND OPENVDB_DEFINITIONS -DTBB_SUPPRESS_DEPRECATED_MESSAGES=1)
+
list(APPEND OPENVDB_INCLUDE_DIRS
${BOOST_INCLUDE_DIR}
${TBB_INCLUDE_DIRS}
@@ -1433,6 +1440,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
# 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()
# versions before gcc4.6 give many BLI_math warnings
@@ -1497,11 +1505,13 @@ if(CMAKE_COMPILER_IS_GNUCC)
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)
@@ -1849,6 +1859,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_FFTW3)
info_cfg_option(WITH_FREESTYLE)
info_cfg_option(WITH_GMP)
+ info_cfg_option(WITH_HARU)
info_cfg_option(WITH_IK_ITASC)
info_cfg_option(WITH_IK_SOLVER)
info_cfg_option(WITH_INPUT_NDOF)
diff --git a/GNUmakefile b/GNUmakefile
index 3b5b9d65521..98463891407 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -183,8 +183,13 @@ endif
ifndef DEPS_INSTALL_DIR
DEPS_INSTALL_DIR:=$(shell dirname "$(BLENDER_DIR)")/lib/$(OS_NCASE)
- ifneq ($(OS_NCASE),darwin)
- # Add processor type to directory name
+ # Add processor type to directory name, except for darwin x86_64
+ # which by convention does not have it.
+ ifeq ($(OS_NCASE),darwin)
+ ifneq ($(CPU),x86_64)
+ DEPS_INSTALL_DIR:=$(DEPS_INSTALL_DIR)_$(CPU)
+ endif
+ else
DEPS_INSTALL_DIR:=$(DEPS_INSTALL_DIR)_$(CPU)
endif
endif
@@ -198,7 +203,7 @@ endif
# in libraries, or python 2 for running make update to get it.
ifeq ($(OS_NCASE),darwin)
ifeq (, $(shell command -v $(PYTHON)))
- PYTHON:=../lib/darwin/python/bin/python3.7m
+ PYTHON:=$(DEPS_INSTALL_DIR)/python/bin/python3.7m
ifeq (, $(shell command -v $(PYTHON)))
PYTHON:=python
endif
@@ -520,7 +525,7 @@ format: .FORCE
# Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation.
doc_py: .FORCE
- ASAN_OPTIONS=halt_on_error=0 \
+ ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
$(BLENDER_BIN) --background -noaudio --factory-startup \
--python doc/python_api/sphinx_doc_gen.py
sphinx-build -b html -j $(NPROCS) doc/python_api/sphinx-in doc/python_api/sphinx-out
diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt
index dfbb0e824a0..672f5820a16 100644
--- a/build_files/build_environment/CMakeLists.txt
+++ b/build_files/build_environment/CMakeLists.txt
@@ -92,6 +92,7 @@ include(cmake/package_python.cmake)
include(cmake/numpy.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.
include(cmake/boost.cmake)
include(cmake/pugixml.cmake)
diff --git a/build_files/build_environment/cmake/haru.cmake b/build_files/build_environment/cmake/haru.cmake
new file mode 100644
index 00000000000..7382095f459
--- /dev/null
+++ b/build_files/build_environment/cmake/haru.cmake
@@ -0,0 +1,46 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(HARU_EXTRA_ARGS
+ -DLIBHPDF_SHARED=OFF
+ -DLIBHPDF_STATIC=ON
+ -DLIBHPDF_EXAMPLES=OFF
+ -DLIBHPDF_ENABLE_EXCEPTIONS=ON
+)
+
+ExternalProject_Add(external_haru
+ URL ${HARU_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${HARU_HASH}
+ PREFIX ${BUILD_DIR}/haru
+ PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/haru/src/external_haru < ${PATCH_DIR}/haru.diff
+ CMAKE_ARGS
+ -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX=${LIBDIR}/haru
+ ${DEFAULT_CMAKE_FLAGS} ${HARU_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/haru
+)
+
+if(WIN32)
+ if(BUILD_MODE STREQUAL Release)
+ ExternalProject_Add_Step(external_haru after_install
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/haru/include ${HARVEST_TARGET}/haru/include
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/haru/lib/libhpdfs.lib ${HARVEST_TARGET}/haru/lib/libhpdfs.lib
+ DEPENDEES install
+ )
+ endif()
+endif()
diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake
index 536907f563d..308cb77144c 100644
--- a/build_files/build_environment/cmake/harvest.cmake
+++ b/build_files/build_environment/cmake/harvest.cmake
@@ -162,7 +162,7 @@ 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}m")
+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")
@@ -187,6 +187,8 @@ 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")
if(UNIX AND NOT APPLE)
harvest(libglu/lib mesa/lib "*.so*")
diff --git a/build_files/build_environment/cmake/numpy.cmake b/build_files/build_environment/cmake/numpy.cmake
index 03316a8fc63..7a1b00895f4 100644
--- a/build_files/build_environment/cmake/numpy.cmake
+++ b/build_files/build_environment/cmake/numpy.cmake
@@ -47,4 +47,5 @@ ExternalProject_Add(external_numpy
add_dependencies(
external_numpy
external_python
+ external_python_site_packages
)
diff --git a/build_files/build_environment/cmake/opencolorio.cmake b/build_files/build_environment/cmake/opencolorio.cmake
index e8b0043edf7..4ad401800d0 100644
--- a/build_files/build_environment/cmake/opencolorio.cmake
+++ b/build_files/build_environment/cmake/opencolorio.cmake
@@ -32,8 +32,8 @@ set(OPENCOLORIO_EXTRA_ARGS
if(APPLE AND NOT("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64"))
set(OPENCOLORIO_EXTRA_ARGS
- ${OPENCOLORIO_EXTRA_ARGS}
- -DOCIO_USE_SSE=OFF
+ ${OPENCOLORIO_EXTRA_ARGS}
+ -DOCIO_USE_SSE=OFF
)
endif()
diff --git a/build_files/build_environment/cmake/python.cmake b/build_files/build_environment/cmake/python.cmake
index bfb318f9939..5731a0e0ae8 100644
--- a/build_files/build_environment/cmake/python.cmake
+++ b/build_files/build_environment/cmake/python.cmake
@@ -43,7 +43,7 @@ if(WIN32)
PREFIX ${BUILD_DIR}/python
CONFIGURE_COMMAND ""
BUILD_COMMAND cd ${BUILD_DIR}/python/src/external_python/pcbuild/ && set IncludeTkinter=false && call build.bat -e -p x64 -c ${BUILD_MODE}
- INSTALL_COMMAND ${PYTHON_BINARY_INTERNAL} ${PYTHON_SRC}/PC/layout/main.py -b ${PYTHON_SRC}/PCbuild/amd64 -s ${PYTHON_SRC} -t ${PYTHON_SRC}/tmp/ --include-underpth --include-stable --include-pip --include-dev --include-launchers --include-venv --include-symbols ${PYTHON_EXTRA_INSTLAL_FLAGS} --copy ${LIBDIR}/python
+ 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
)
else()
@@ -74,12 +74,11 @@ else()
endif()
set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV} && ${PYTHON_FUNC_CONFIGS})
set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python.exe)
- set(PYTHON_PATCH ${PATCH_CMD} --verbose -p1 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_macos.diff)
else()
set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV})
set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python)
set(PYTHON_PATCH ${PATCH_CMD} --verbose -p1 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_linux.diff)
- endif()
+ endif()
set(PYTHON_CONFIGURE_EXTRA_ARGS "--with-openssl=${LIBDIR}/ssl")
set(PYTHON_CFLAGS "-I${LIBDIR}/sqlite/include -I${LIBDIR}/bzip2/include -I${LIBDIR}/lzma/include -I${LIBDIR}/zlib/include")
diff --git a/build_files/build_environment/cmake/python_site_packages.cmake b/build_files/build_environment/cmake/python_site_packages.cmake
index d17f65a152b..a3b9c3bf796 100644
--- a/build_files/build_environment/cmake/python_site_packages.cmake
+++ b/build_files/build_environment/cmake/python_site_packages.cmake
@@ -16,12 +16,16 @@
#
# ***** END GPL LICENSE BLOCK *****
+if(WIN32 AND BUILD_MODE STREQUAL Debug)
+ set(SITE_PACKAGES_EXTRA --global-option build --global-option --debug)
+endif()
+
ExternalProject_Add(external_python_site_packages
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
PREFIX ${BUILD_DIR}/site_packages
- INSTALL_COMMAND ${PYTHON_BINARY} -m pip install idna==${IDNA_VERSION} chardet==${CHARDET_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} --no-binary :all:
+ INSTALL_COMMAND ${PYTHON_BINARY} -m pip install ${SITE_PACKAGES_EXTRA} cython==${CYTHON_VERSION} idna==${IDNA_VERSION} chardet==${CHARDET_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} --no-binary :all:
)
add_dependencies(
diff --git a/build_files/build_environment/cmake/ssl.cmake b/build_files/build_environment/cmake/ssl.cmake
index e1c168817f4..e6741ebb385 100644
--- a/build_files/build_environment/cmake/ssl.cmake
+++ b/build_files/build_environment/cmake/ssl.cmake
@@ -20,7 +20,7 @@ set(SSL_CONFIGURE_COMMAND ./Configure)
set(SSL_PATCH_CMD echo .)
if(APPLE)
- set(SSL_OS_COMPILER "blender-darwin-${CMAKE_OSX_ARCHITECTURES}")
+ set(SSL_OS_COMPILER "blender-darwin-${CMAKE_OSX_ARCHITECTURES}")
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(SSL_EXTRA_ARGS enable-ec_nistp_64_gcc_128)
diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake
index d4a2c715ecc..76417b59bb3 100644
--- a/build_files/build_environment/cmake/versions.cmake
+++ b/build_files/build_environment/cmake/versions.cmake
@@ -138,11 +138,11 @@ set(OSL_VERSION 1.10.10)
set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.tar.gz)
set(OSL_HASH 00dec08a93c8084e53848b9ad047889f)
-set(PYTHON_VERSION 3.7.7)
-set(PYTHON_SHORT_VERSION 3.7)
-set(PYTHON_SHORT_VERSION_NO_DOTS 37)
+set(PYTHON_VERSION 3.9.1)
+set(PYTHON_SHORT_VERSION 3.9)
+set(PYTHON_SHORT_VERSION_NO_DOTS 39)
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
-set(PYTHON_HASH 172c650156f7bea68ce31b2fd01fa766)
+set(PYTHON_HASH 61981498e75ac8f00adcb908281fadb6)
set(TBB_VERSION 2019_U9)
set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz)
@@ -156,16 +156,17 @@ set(NANOVDB_GIT_UID e62f7a0bf1e27397223c61ddeaaf57edf111b77f)
set(NANOVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/${NANOVDB_GIT_UID}.tar.gz)
set(NANOVDB_HASH 90919510bc6ccd630fedc56f748cb199)
-set(IDNA_VERSION 2.9)
-set(CHARDET_VERSION 3.0.4)
-set(URLLIB3_VERSION 1.25.9)
-set(CERTIFI_VERSION 2020.4.5.2)
-set(REQUESTS_VERSION 2.23.0)
+set(IDNA_VERSION 2.10)
+set(CHARDET_VERSION 4.0.0)
+set(URLLIB3_VERSION 1.26.3)
+set(CERTIFI_VERSION 2020.12.5)
+set(REQUESTS_VERSION 2.25.1)
+set(CYTHON_VERSION 0.29.21)
-set(NUMPY_VERSION 1.17.5)
-set(NUMPY_SHORT_VERSION 1.17)
+set(NUMPY_VERSION 1.19.5)
+set(NUMPY_SHORT_VERSION 1.19)
set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}/numpy-${NUMPY_VERSION}.zip)
-set(NUMPY_HASH 763a5646fa6eef7a22f4895bca0524f2)
+set(NUMPY_HASH f6a1b48717c552bbc18f1adc3cc1fe0e)
set(LAME_VERSION 3.100)
set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.100/lame-${LAME_VERSION}.tar.gz)
@@ -265,7 +266,7 @@ set(PUGIXML_URI https://github.com/zeux/pugixml/archive/v${PUGIXML_VERSION}.tar.
set(PUGIXML_HASH 0c208b0664c7fb822bf1b49ad035e8fd)
set(FLEXBISON_VERSION 2.5.5)
-set(FLEXBISON_URI http://prdownloads.sourceforge.net/winflexbison//win_flex_bison-2.5.5.zip)
+set(FLEXBISON_URI http://prdownloads.sourceforge.net/winflexbison/win_flex_bison-2.5.5.zip)
set(FLEXBISON_HASH d87a3938194520d904013abef3df10ce)
# Libraries to keep Python modules static on Linux.
@@ -309,7 +310,7 @@ set(LIBGLU_URI ftp://ftp.freedesktop.org/pub/mesa/glu/glu-${LIBGLU_VERSION}.tar.
set(LIBGLU_HASH 151aef599b8259efe9acd599c96ea2a3)
set(MESA_VERSION 18.3.1)
-set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa//mesa-${MESA_VERSION}.tar.xz)
+set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa/mesa-${MESA_VERSION}.tar.xz)
set(MESA_HASH d60828056d77bfdbae0970f9b15fb1be)
set(NASM_VERSION 2.15.02)
@@ -331,3 +332,7 @@ set(GMP_HASH a325e3f09e6d91e62101e59f9bda3ec1)
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(HARU_VERSION 2_3_0)
+set(HARU_URI https://github.com/libharu/libharu/archive/RELEASE_${HARU_VERSION}.tar.gz)
+set(HARU_HASH 4f916aa49c3069b3a10850013c507460)
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 671417214d8..da2a6535142 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -53,15 +53,15 @@ getopt \
--long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,\
with-all,with-opencollada,with-jack,with-embree,with-oidn,with-nanovdb,\
ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,ver-xr-openxr:,\
-force-all,force-python,force-numpy,force-boost,force-tbb,\
+force-all,force-python,force-boost,force-tbb,\
force-ocio,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,\
-build-all,build-python,build-numpy,build-boost,build-tbb,\
+build-all,build-python,build-boost,build-tbb,\
build-ocio,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,\
-skip-python,skip-numpy,skip-boost,skip-tbb,\
+skip-python,skip-boost,skip-tbb,\
skip-ocio,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 \
@@ -188,9 +188,6 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--build-python
Force the build of Python.
- --build-numpy
- Force the build of NumPy.
-
--build-boost
Force the build of Boost.
@@ -255,9 +252,6 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--force-python
Force the rebuild of Python.
- --force-numpy
- Force the rebuild of NumPy.
-
--force-boost
Force the rebuild of Boost.
@@ -315,9 +309,6 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--skip-python
Unconditionally skip Python installation/building.
- --skip-numpy
- Unconditionally skip NumPy installation/building.
-
--skip-boost
Unconditionally skip Boost installation/building.
@@ -385,36 +376,80 @@ USE_CXX11=true
CLANG_FORMAT_VERSION_MIN="6.0"
CLANG_FORMAT_VERSION_MAX="10.0"
-PYTHON_VERSION="3.7.7"
-PYTHON_VERSION_SHORT="3.7"
+PYTHON_VERSION="3.9.1"
+PYTHON_VERSION_SHORT="3.9"
PYTHON_VERSION_MIN="3.7"
-PYTHON_VERSION_MAX="3.9"
-PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_MIN
+PYTHON_VERSION_MAX="3.10"
+PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_SHORT
PYTHON_FORCE_BUILD=false
PYTHON_FORCE_REBUILD=false
PYTHON_SKIP=false
-NUMPY_VERSION="1.17.5"
-NUMPY_VERSION_SHORT="1.17"
-NUMPY_VERSION_MIN="1.8"
-NUMPY_VERSION_MAX="2.0"
-NUMPY_FORCE_BUILD=false
-NUMPY_FORCE_REBUILD=false
-NUMPY_SKIP=false
+# Additional Python modules.
+PYTHON_IDNA_VERSION="2.9"
+PYTHON_IDNA_VERSION_MIN="2.0"
+PYTHON_IDNA_VERSION_MAX="3.0"
+PYTHON_IDNA_NAME="idna"
+
+PYTHON_CHARDET_VERSION="3.0.4"
+PYTHON_CHARDET_VERSION_MIN="3.0"
+PYTHON_CHARDET_VERSION_MAX="5.0"
+PYTHON_CHARDET_NAME="chardet"
+
+PYTHON_URLLIB3_VERSION="1.25.9"
+PYTHON_URLLIB3_VERSION_MIN="1.0"
+PYTHON_URLLIB3_VERSION_MAX="2.0"
+PYTHON_URLLIB3_NAME="urllib3"
+
+PYTHON_CERTIFI_VERSION="2020.4.5.2"
+PYTHON_CERTIFI_VERSION_MIN="2020.0"
+PYTHON_CERTIFI_VERSION_MAX="2021.0"
+PYTHON_CERTIFI_NAME="certifi"
+
+PYTHON_REQUESTS_VERSION="2.23.0"
+PYTHON_REQUESTS_VERSION_MIN="2.0"
+PYTHON_REQUESTS_VERSION_MAX="3.0"
+PYTHON_REQUESTS_NAME="requests"
+
+PYTHON_NUMPY_VERSION="1.19.5"
+PYTHON_NUMPY_VERSION_MIN="1.14"
+PYTHON_NUMPY_VERSION_MAX="2.0"
+PYTHON_NUMPY_NAME="numpy"
+
+# As package-ready parameters (only used with distro packages).
+PYTHON_MODULES_PACKAGES=(
+ "$PYTHON_IDNA_NAME $PYTHON_IDNA_VERSION_MIN $PYTHON_IDNA_VERSION_MAX"
+ "$PYTHON_CHARDET_NAME $PYTHON_CHARDET_VERSION_MIN $PYTHON_CHARDET_VERSION_MAX"
+ "$PYTHON_URLLIB3_NAME $PYTHON_URLLIB3_VERSION_MIN $PYTHON_URLLIB3_VERSION_MAX"
+ "$PYTHON_CERTIFI_NAME $PYTHON_CERTIFI_VERSION_MIN $PYTHON_CERTIFI_VERSION_MAX"
+ "$PYTHON_REQUESTS_NAME $PYTHON_REQUESTS_VERSION_MIN $PYTHON_REQUESTS_VERSION_MAX"
+ "$PYTHON_NUMPY_NAME $PYTHON_NUMPY_VERSION_MIN $PYTHON_NUMPY_VERSION_MAX"
+)
-BOOST_VERSION="1.70.0"
-BOOST_VERSION_SHORT="1.70"
+# As pip-ready parameters (only used when building python).
+PYTHON_MODULES_PIP=(
+ "$PYTHON_IDNA_NAME==$PYTHON_IDNA_VERSION"
+ "$PYTHON_CHARDET_NAME==$PYTHON_CHARDET_VERSION"
+ "$PYTHON_URLLIB3_NAME==$PYTHON_URLLIB3_VERSION"
+ "$PYTHON_CERTIFI_NAME==$PYTHON_CERTIFI_VERSION"
+ "$PYTHON_REQUESTS_NAME==$PYTHON_REQUESTS_VERSION"
+ "$PYTHON_NUMPY_NAME==$PYTHON_NUMPY_VERSION"
+)
+
+
+BOOST_VERSION="1.73.0"
+BOOST_VERSION_SHORT="1.73"
BOOST_VERSION_MIN="1.49"
BOOST_VERSION_MAX="2.0"
BOOST_FORCE_BUILD=false
BOOST_FORCE_REBUILD=false
BOOST_SKIP=false
-TBB_VERSION="2019"
-TBB_VERSION_SHORT="2019"
-TBB_VERSION_UPDATE="_U9" # Used for source packages...
+TBB_VERSION="2020"
+TBB_VERSION_SHORT="2020"
+TBB_VERSION_UPDATE="_U2" # Used for source packages...
TBB_VERSION_MIN="2018"
-TBB_VERSION_MAX="2021"
+TBB_VERSION_MAX="2022"
TBB_FORCE_BUILD=false
TBB_FORCE_REBUILD=false
TBB_SKIP=false
@@ -439,7 +474,7 @@ _with_built_openexr=false
OIIO_VERSION="2.1.15.0"
OIIO_VERSION_SHORT="2.1"
OIIO_VERSION_MIN="2.1.12"
-OIIO_VERSION_MAX="3.0"
+OIIO_VERSION_MAX="2.2.10"
OIIO_FORCE_BUILD=false
OIIO_FORCE_REBUILD=false
OIIO_SKIP=false
@@ -447,16 +482,16 @@ OIIO_SKIP=false
LLVM_VERSION="9.0.1"
LLVM_VERSION_SHORT="9.0"
LLVM_VERSION_MIN="6.0"
-LLVM_VERSION_MAX="11.0"
+LLVM_VERSION_MAX="12.0"
LLVM_VERSION_FOUND=""
LLVM_FORCE_BUILD=false
LLVM_FORCE_REBUILD=false
LLVM_SKIP=false
# OSL needs to be compiled for now!
-OSL_VERSION="1.10.10"
-OSL_VERSION_SHORT="1.10"
-OSL_VERSION_MIN="1.10"
+OSL_VERSION="1.11.10.0"
+OSL_VERSION_SHORT="1.11"
+OSL_VERSION_MIN="1.11"
OSL_VERSION_MAX="2.0"
OSL_FORCE_BUILD=false
OSL_FORCE_REBUILD=false
@@ -474,16 +509,16 @@ OSD_SKIP=false
# OpenVDB needs to be compiled for now
OPENVDB_BLOSC_VERSION="1.5.0"
-OPENVDB_VERSION="7.0.0"
-OPENVDB_VERSION_SHORT="7.0"
-OPENVDB_VERSION_MIN="7.0"
-OPENVDB_VERSION_MAX="7.1"
+OPENVDB_VERSION="8.0.1"
+OPENVDB_VERSION_SHORT="8.0"
+OPENVDB_VERSION_MIN="8.0"
+OPENVDB_VERSION_MAX="8.1"
OPENVDB_FORCE_BUILD=false
OPENVDB_FORCE_REBUILD=false
OPENVDB_SKIP=false
# Alembic needs to be compiled for now
-ALEMBIC_VERSION="1.7.12"
+ALEMBIC_VERSION="1.7.16"
ALEMBIC_VERSION_SHORT="1.7"
ALEMBIC_VERSION_MIN="1.7"
ALEMBIC_VERSION_MAX="2.0"
@@ -491,10 +526,10 @@ ALEMBIC_FORCE_BUILD=false
ALEMBIC_FORCE_REBUILD=false
ALEMBIC_SKIP=false
-USD_VERSION="20.05"
-USD_VERSION_SHORT="20.05"
+USD_VERSION="20.08"
+USD_VERSION_SHORT="20.08"
USD_VERSION_MIN="20.05"
-USD_VERSION_MAX="20.06"
+USD_VERSION_MAX="21.00"
USD_FORCE_BUILD=false
USD_FORCE_REBUILD=false
USD_SKIP=false
@@ -515,10 +550,10 @@ EMBREE_FORCE_BUILD=false
EMBREE_FORCE_REBUILD=false
EMBREE_SKIP=false
-OIDN_VERSION="1.2.3"
-OIDN_VERSION_SHORT="1.2"
-OIDN_VERSION_MIN="1.2.0"
-OIDN_VERSION_MAX="1.3"
+OIDN_VERSION="1.3.0"
+OIDN_VERSION_SHORT="1.3"
+OIDN_VERSION_MIN="1.3.0"
+OIDN_VERSION_MAX="1.4"
OIDN_FORCE_BUILD=false
OIDN_FORCE_REBUILD=false
OIDN_SKIP=false
@@ -534,7 +569,7 @@ FFMPEG_FORCE_REBUILD=false
FFMPEG_SKIP=false
_ffmpeg_list_sep=";"
-XR_OPENXR_VERSION="1.0.8"
+XR_OPENXR_VERSION="1.0.14"
XR_OPENXR_VERSION_SHORT="1.0"
XR_OPENXR_VERSION_MIN="1.0.8"
XR_OPENXR_VERSION_MAX="2.0"
@@ -730,7 +765,6 @@ while true; do
;;
--build-all)
PYTHON_FORCE_BUILD=true
- NUMPY_FORCE_BUILD=true
BOOST_FORCE_BUILD=true
TBB_FORCE_BUILD=true
OCIO_FORCE_BUILD=true
@@ -751,12 +785,6 @@ while true; do
;;
--build-python)
PYTHON_FORCE_BUILD=true
- NUMPY_FORCE_BUILD=true
- shift; continue
- ;;
- --build-numpy)
- PYTHON_FORCE_BUILD=true
- NUMPY_FORCE_BUILD=true
shift; continue
;;
--build-boost)
@@ -809,7 +837,6 @@ while true; do
;;
--force-all)
PYTHON_FORCE_REBUILD=true
- NUMPY_FORCE_REBUILD=true
BOOST_FORCE_REBUILD=true
TBB_FORCE_REBUILD=true
OCIO_FORCE_REBUILD=true
@@ -830,12 +857,8 @@ while true; do
;;
--force-python)
PYTHON_FORCE_REBUILD=true
- NUMPY_FORCE_REBUILD=true
shift; continue
;;
- --force-numpy)
- NUMPY_FORCE_REBUILD=true; shift; continue
- ;;
--force-boost)
BOOST_FORCE_REBUILD=true; shift; continue
;;
@@ -887,9 +910,6 @@ while true; do
--skip-python)
PYTHON_SKIP=true; shift; continue
;;
- --skip-numpy)
- NUMPY_SKIP=true; shift; continue
- ;;
--skip-boost)
BOOST_SKIP=true; shift; continue
;;
@@ -990,11 +1010,10 @@ PRINT ""
# This has to be done here, because user might force some versions...
PYTHON_SOURCE=( "https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tgz" )
-NUMPY_SOURCE=( "https://github.com/numpy/numpy/releases/download/v$NUMPY_VERSION/numpy-$NUMPY_VERSION.tar.gz" )
_boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'`
BOOST_SOURCE=( "https://dl.bintray.com/boostorg/release/$BOOST_VERSION/source/boost_$_boost_version_nodots.tar.bz2" )
-BOOST_BUILD_MODULES="--with-system --with-filesystem --with-thread --with-regex --with-locale --with-date_time --with-wave --with-iostreams --with-python --with-program_options"
+BOOST_BUILD_MODULES="--with-system --with-filesystem --with-thread --with-regex --with-locale --with-date_time --with-wave --with-iostreams --with-python --with-program_options --with-serialization --with-atomic"
TBB_SOURCE=( "https://github.com/oneapi-src/oneTBB/archive/$TBB_VERSION$TBB_VERSION_UPDATE.tar.gz" )
TBB_SOURCE_CMAKE=( "https://raw.githubusercontent.com/wjakob/tbb/master/CMakeLists.txt" )
@@ -1082,8 +1101,8 @@ FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" )
XR_OPENXR_USE_REPO=false
XR_OPENXR_SOURCE=("https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_VERSION}.tar.gz")
-#~ XR_OPENXR_SOURCE_REPO=("https://github.com/KhronosGroup/OpenXR-SDK-Source.git")
-#~ XR_OPENXR_REPO_UID="5292e57fda47561e672fba0a4b6e545c0f25dd8d"
+#~ XR_OPENXR_SOURCE_REPO=("https://github.com/KhronosGroup/OpenXR-SDK.git")
+#~ XR_OPENXR_REPO_UID="5900c51562769b03bea699dc0352cae56acb6419d"
#~ XR_OPENXR_REPO_BRANCH="master"
# C++11 is required now
@@ -1103,7 +1122,7 @@ Those libraries should be available as packages in all recent distributions (opt
* libjpeg, libpng, libtiff, [openjpeg2], [libopenal].
* libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed).
* libsqlite3, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp.
- * libsdl2, libglew, libpugixml, libpotrace, [libgmp], [libglewmx], fontconfig.\""
+ * libsdl2, libglew, libpugixml, libpotrace, [libgmp], [libglewmx], fontconfig, [libharu/libhpdf].\""
DEPS_SPECIFIC_INFO="\"BUILDABLE DEPENDENCIES:
@@ -1112,19 +1131,24 @@ The following libraries will probably not all be available as packages in your d
You can force install_deps to build those with '--build-all' or relevant 'build-foo' options, see '--help' message.
You may also want to build them yourself (optional ones are [between brackets]):
- * Python $PYTHON_VERSION_MIN (from $PYTHON_SOURCE).
- * [NumPy $NUMPY_VERSION_MIN] (from $NUMPY_SOURCE).
- * Boost $BOOST_VERSION_MIN (from $BOOST_SOURCE, modules: $BOOST_BUILD_MODULES).
- * TBB $TBB_VERSION_MIN (from $TBB_SOURCE).
- * [FFMpeg $FFMPEG_VERSION_MIN (needs libvorbis, libogg, libtheora, libx264, libmp3lame, libxvidcore, libvpx, ...)] (from $FFMPEG_SOURCE).
- * [OpenColorIO $OCIO_VERSION_MIN] (from $OCIO_SOURCE).
- * ILMBase $OPENEXR_VERSION_MIN (from $OPENEXR_SOURCE).
- * OpenEXR $OPENEXR_VERSION_MIN (from $OPENEXR_SOURCE).
- * OpenImageIO $OIIO_VERSION_MIN (from $OIIO_SOURCE).
- * [LLVM $LLVM_VERSION_MIN (with clang)] (from $LLVM_SOURCE, and $LLVM_CLANG_SOURCE).
- * [OpenShadingLanguage $OSL_VERSION_MIN] (from $OSL_SOURCE_REPO, branch $OSL_SOURCE_REPO_BRANCH, commit $OSL_SOURCE_REPO_UID).
- * [OpenSubDiv $OSD_VERSION_MIN] (from $OSD_SOURCE_REPO, branch $OSD_SOURCE_REPO_BRANCH, commit $OSD_SOURCE_REPO_UID).
- * [OpenVDB $OPENVDB_VERSION_MIN] (from $OPENVDB_SOURCE), [Blosc $OPENVDB_BLOSC_VERSION] (from $OPENVDB_BLOSC_SOURCE).
+ * Python $PYTHON_VERSION (from $PYTHON_SOURCE).
+ ** [IDNA $PYTHON_IDNA_VERSION] (use pip).
+ ** [Chardet $PYTHON_CHARDET_VERSION] (use pip).
+ ** [Urllib3 $PYTHON_URLLIB3_VERSION] (use pip).
+ ** [Certifi $PYTHON_CERTIFI_VERSION] (use pip).
+ ** [Requests $PYTHON_REQUESTS_VERSION] (use pip).
+ ** [NumPy $PYTHON_NUMPY_VERSION] (use pip).
+ * Boost $BOOST_VERSION (from $BOOST_SOURCE, modules: $BOOST_BUILD_MODULES).
+ * TBB $TBB_VERSION (from $TBB_SOURCE).
+ * [FFMpeg $FFMPEG_VERSION (needs libvorbis, libogg, libtheora, libx264, libmp3lame, libxvidcore, libvpx, ...)] (from $FFMPEG_SOURCE).
+ * [OpenColorIO $OCIO_VERSION] (from $OCIO_SOURCE).
+ * ILMBase $OPENEXR_VERSION (from $OPENEXR_SOURCE).
+ * OpenEXR $OPENEXR_VERSION (from $OPENEXR_SOURCE).
+ * OpenImageIO $OIIO_VERSION (from $OIIO_SOURCE).
+ * [LLVM $LLVM_VERSION (with clang)] (from $LLVM_SOURCE, and $LLVM_CLANG_SOURCE).
+ * [OpenShadingLanguage $OSL_VERSION] (from $OSL_SOURCE_REPO, branch $OSL_SOURCE_REPO_BRANCH, commit $OSL_SOURCE_REPO_UID).
+ * [OpenSubDiv $OSD_VERSION] (from $OSD_SOURCE_REPO, branch $OSD_SOURCE_REPO_BRANCH, commit $OSD_SOURCE_REPO_UID).
+ * [OpenVDB $OPENVDB_VERSION] (from $OPENVDB_SOURCE), [Blosc $OPENVDB_BLOSC_VERSION] (from $OPENVDB_BLOSC_SOURCE).
* [OpenCollada $OPENCOLLADA_VERSION] (from $OPENCOLLADA_SOURCE).
* [Embree $EMBREE_VERSION] (from $EMBREE_SOURCE).
* [OpenImageDenoise $OIDN_VERSION] (from $OIDN_SOURCE).
@@ -1309,18 +1333,22 @@ magic_compile_set() {
# Note: should clean nicely in $INST, but not in $SRC, when we switch to a new version of a lib...
_clean() {
- rm -rf `readlink -f $_inst_shortcut`
+ if [ $_inst_shortcut ]; then
+ rm -rf `readlink -f $_inst_shortcut`
+ rm -rf $_inst_shortcut
+ fi
# Only remove $_src dir when not using git repo (avoids to re-clone the whole repo every time!!!).
if [ $_git == false ]; then
rm -rf $_src
fi
rm -rf $_inst
- rm -rf $_inst_shortcut
}
_create_inst_shortcut() {
- rm -f $_inst_shortcut
- ln -s $_inst $_inst_shortcut
+ if [ $_inst_shortcut ]; then
+ rm -f $_inst_shortcut
+ ln -s $_inst $_inst_shortcut
+ fi
}
# ldconfig
@@ -1350,14 +1378,19 @@ _init_python() {
}
_update_deps_python() {
- :
+ if [ "$1" = true ]; then
+ BOOST_FORCE_BUILD=true
+ fi
+ if [ "$2" = true ]; then
+ BOOST_FORCE_REBUILD=true
+ fi
}
clean_Python() {
- clean_Numpy
_init_python
if [ -d $_inst ]; then
- _update_deps_python
+ # Force rebuilding the dependencies if needed.
+ _update_deps_python false true
fi
_clean
}
@@ -1369,9 +1402,12 @@ compile_Python() {
fi
# To be changed each time we make edits that would modify the compiled result!
- py_magic=1
+ py_magic=3
_init_python
+ # Force having own builds for the dependencies.
+ _update_deps_python true false
+
# Clean install if needed!
magic_compile_check python-$PYTHON_VERSION $py_magic
if [ $? -eq 1 -o "$PYTHON_FORCE_REBUILD" = true ]; then
@@ -1380,10 +1416,9 @@ compile_Python() {
if [ ! -d $_inst ]; then
INFO "Building Python-$PYTHON_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_python
+ # Force rebuilding the dependencies.
+ _update_deps_python true true
prepare_inst
@@ -1413,96 +1448,25 @@ compile_Python() {
magic_compile_set python-$PYTHON_VERSION $py_magic
+ PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_SHORT
+
cd $CWD
INFO "Done compiling Python-$PYTHON_VERSION!"
- _is_building=false
else
INFO "Own Python-$PYTHON_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-python option."
fi
run_ldconfig "python-$PYTHON_VERSION_SHORT"
-}
-
-# ----------------------------------------------------------------------------
-# Build Numpy
-
-_init_numpy() {
- _src=$SRC/numpy-$NUMPY_VERSION
- _git=false
- _inst=$INST/numpy-$NUMPY_VERSION
- _python=$INST/python-$PYTHON_VERSION_SHORT
- _site=lib/python$PYTHON_VERSION_SHORT/site-packages
- _inst_shortcut=$_python/$_site/numpy
-}
-
-_update_deps_numpy() {
- :
-}
-
-clean_Numpy() {
- _init_numpy
- if [ -d $_inst ]; then
- _update_deps_numpy
- fi
- _clean
-}
-compile_Numpy() {
- if [ "$NO_BUILD" = true ]; then
- WARNING "--no-build enabled, Numpy will not be compiled!"
- return
- fi
-
- # To be changed each time we make edits that would modify the compiled result!
- numpy_magic=0
- _init_numpy
-
- # Clean install if needed!
- magic_compile_check numpy-$NUMPY_VERSION $numpy_magic
- if [ $? -eq 1 -o "$NUMPY_FORCE_REBUILD" = true ]; then
- clean_Numpy
- fi
-
- if [ ! -d $_inst ]; then
- INFO "Building Numpy-$NUMPY_VERSION"
- _is_building=true
-
- # Rebuild dependencies as well!
- _update_deps_numpy
-
- prepare_inst
-
- if [ ! -d $_src ]; then
- mkdir -p $SRC
- download NUMPY_SOURCE[@] $_src.tar.gz
-
- INFO "Unpacking Numpy-$NUMPY_VERSION"
- tar -C $SRC -xf $_src.tar.gz
- fi
-
- cd $_src
-
- $_python/bin/python3 setup.py install --old-and-unmanageable --prefix=$_inst
-
- if [ -d $_inst ]; then
- # Can't use _create_inst_shortcut here...
- rm -f $_inst_shortcut
- ln -s $_inst/$_site/numpy $_inst_shortcut
- else
- ERROR "Numpy-$NUMPY_VERSION failed to compile, exiting"
- exit 1
- fi
-
- magic_compile_set numpy-$NUMPY_VERSION $numpy_magic
-
- cd $CWD
- INFO "Done compiling Numpy-$NUMPY_VERSION!"
- _is_building=false
- else
- INFO "Own Numpy-$NUMPY_VERSION is up to date, nothing to do!"
- INFO "If you want to force rebuild of this lib, use the --force-numpy option."
- fi
+ # Extra step: install required modules with pip.
+ _python="$_inst/bin/python3"
+ $_python -m pip install --upgrade pip
+ for module in "${PYTHON_MODULES_PIP[@]}"
+ do
+ PRINT ""
+ $_python -m pip install $module --no-binary :all:
+ done
}
# ----------------------------------------------------------------------------
@@ -1516,22 +1480,25 @@ _init_boost() {
}
_update_deps_boost() {
- OIIO_FORCE_REBUILD=true
- OSL_FORCE_REBUILD=true
- OPENVDB_FORCE_REBUILD=true
- ALEMBIC_FORCE_REBUILD=true
- if [ "$_is_building" = true ]; then
+ if [ "$1" = true ]; then
OIIO_FORCE_BUILD=true
OSL_FORCE_BUILD=true
OPENVDB_FORCE_BUILD=true
ALEMBIC_FORCE_BUILD=true
fi
+ if [ "$2" = true ]; then
+ OIIO_FORCE_REBUILD=true
+ OSL_FORCE_REBUILD=true
+ OPENVDB_FORCE_REBUILD=true
+ ALEMBIC_FORCE_REBUILD=true
+ fi
}
clean_Boost() {
_init_boost
if [ -d $_inst ]; then
- _update_deps_boost
+ # Force rebuilding the dependencies if needed.
+ _update_deps_boost false true
fi
_clean
}
@@ -1543,10 +1510,13 @@ compile_Boost() {
fi
# To be changed each time we make edits that would modify the compiled result!
- boost_magic=11
+ boost_magic=14
_init_boost
+ # Force having own builds for the dependencies.
+ _update_deps_boost true false
+
# Clean install if needed!
magic_compile_check boost-$BOOST_VERSION $boost_magic
if [ $? -eq 1 -o "$BOOST_FORCE_REBUILD" = true ]; then
@@ -1555,10 +1525,9 @@ compile_Boost() {
if [ ! -d $_inst ]; then
INFO "Building Boost-$BOOST_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_boost
+ # Force rebuilding the dependencies.
+ _update_deps_boost true true
prepare_inst
@@ -1571,7 +1540,11 @@ compile_Boost() {
cd $_src
if [ ! -f $_src/b2 ]; then
- ./bootstrap.sh
+ if [ -d $INST/python-$PYTHON_VERSION_INSTALLED ]; then
+ ./bootstrap.sh --with-python-root="$INST/python-$PYTHON_VERSION_INSTALLED"
+ else
+ ./bootstrap.sh
+ fi
fi
./b2 -j$THREADS -a $BOOST_BUILD_MODULES \
--prefix=$_inst --disable-icu boost.locale.icu=off install
@@ -1588,7 +1561,6 @@ compile_Boost() {
cd $CWD
INFO "Done compiling Boost-$BOOST_VERSION!"
- _is_building=false
else
INFO "Own Boost-$BOOST_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-boost option."
@@ -1609,24 +1581,27 @@ _init_tbb() {
}
_update_deps_tbb() {
- OSD_FORCE_REBUILD=true
- OPENVDB_FORCE_REBUILD=true
- USD_FORCE_REBUILD=true
- EMBREE_FORCE_REBUILD=true
- OIDN_FORCE_REBUILD=true
- if [ "$_is_building" = true ]; then
+ if [ "$1" = true ]; then
OSD_FORCE_BUILD=true
OPENVDB_FORCE_BUILD=true
USD_FORCE_BUILD=true
EMBREE_FORCE_BUILD=true
OIDN_FORCE_BUILD=true
fi
+ if [ "$2" = true ]; then
+ OSD_FORCE_REBUILD=true
+ OPENVDB_FORCE_REBUILD=true
+ USD_FORCE_REBUILD=true
+ EMBREE_FORCE_REBUILD=true
+ OIDN_FORCE_REBUILD=true
+ fi
}
clean_TBB() {
_init_tbb
if [ -d $_inst ]; then
- _update_deps_tbb
+ # Force rebuilding the dependencies if needed.
+ _update_deps_tbb false true
fi
_clean
}
@@ -1641,6 +1616,9 @@ compile_TBB() {
tbb_magic=0
_init_tbb
+ # Force having own builds for the dependencies.
+ _update_deps_tbb true false
+
# Clean install if needed!
magic_compile_check tbb-$TBB_VERSION $tbb_magic
if [ $? -eq 1 -o "$TBB_FORCE_REBUILD" = true ]; then
@@ -1649,10 +1627,9 @@ compile_TBB() {
if [ ! -d $_inst ]; then
INFO "Building TBB-$TBB_VERSION$TBB_VERSION_UPDATE"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_tbb
+ # Force rebuilding the dependencies.
+ _update_deps_tbb true true
prepare_inst
@@ -1713,7 +1690,6 @@ compile_TBB() {
cd $CWD
INFO "Done compiling TBB-$TBB_VERSION$TBB_VERSION_UPDATE!"
- _is_building=false
else
INFO "Own TBB-$TBB_VERSION$TBB_VERSION_UPDATE is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-tbb option."
@@ -1743,7 +1719,8 @@ _update_deps_ocio() {
clean_OCIO() {
_init_ocio
if [ -d $_inst ]; then
- _update_deps_ocio
+ # Force rebuilding the dependencies if needed.
+ _update_deps_ocio false true
fi
_clean
}
@@ -1758,6 +1735,9 @@ compile_OCIO() {
ocio_magic=2
_init_ocio
+ # Force having own builds for the dependencies.
+ _update_deps_ocio true false
+
# Clean install if needed!
magic_compile_check ocio-$OCIO_VERSION $ocio_magic
if [ $? -eq 1 -o "$OCIO_FORCE_REBUILD" = true ]; then
@@ -1766,10 +1746,9 @@ compile_OCIO() {
if [ ! -d $_inst ]; then
INFO "Building OpenColorIO-$OCIO_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_ocio
+ # Force rebuilding the dependencies.
+ _update_deps_ocio true true
prepare_inst
@@ -1842,7 +1821,6 @@ compile_OCIO() {
cd $CWD
INFO "Done compiling OpenColorIO-$OCIO_VERSION!"
- _is_building=false
else
INFO "Own OpenColorIO-$OCIO_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-ocio option."
@@ -1862,18 +1840,21 @@ _init_openexr() {
}
_update_deps_openexr() {
- OIIO_FORCE_REBUILD=true
- ALEMBIC_FORCE_REBUILD=true
- if [ "$_is_building" = true ]; then
+ if [ "$1" = true ]; then
OIIO_FORCE_BUILD=true
ALEMBIC_FORCE_BUILD=true
fi
+ if [ "$2" = true ]; then
+ OIIO_FORCE_REBUILD=true
+ ALEMBIC_FORCE_REBUILD=true
+ fi
}
clean_OPENEXR() {
_init_openexr
if [ -d $_inst ]; then
- _update_deps_openexr
+ # Force rebuilding the dependencies if needed.
+ _update_deps_openexr false true
fi
_clean
}
@@ -1886,6 +1867,10 @@ compile_OPENEXR() {
# To be changed each time we make edits that would modify the compiled result!
openexr_magic=15
+ _init_openexr
+
+ # Force having own builds for the dependencies.
+ _update_deps_openexr true false
# Clean install if needed!
magic_compile_check openexr-$OPENEXR_VERSION $openexr_magic
@@ -1894,14 +1879,12 @@ compile_OPENEXR() {
fi
PRINT ""
- _init_openexr
if [ ! -d $_inst ]; then
INFO "Building ILMBase-$OPENEXR_VERSION and OpenEXR-$OPENEXR_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_openexr
+ # Force rebuilding the dependencies.
+ _update_deps_openexr true true
prepare_inst
@@ -1969,7 +1952,6 @@ compile_OPENEXR() {
cd $CWD
INFO "Done compiling OpenEXR-$OPENEXR_VERSION!"
- _is_building=false
else
INFO "Own OpenEXR-$OPENEXR_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-openexr option."
@@ -1992,16 +1974,19 @@ _init_oiio() {
}
_update_deps_oiio() {
- OSL_FORCE_REBUILD=true
- if [ "$_is_building" = true ]; then
+ if [ "$1" = true ]; then
OSL_FORCE_BUILD=true
fi
+ if [ "$2" = true ]; then
+ OSL_FORCE_REBUILD=true
+ fi
}
clean_OIIO() {
_init_oiio
if [ -d $_inst ]; then
- _update_deps_oiio
+ # Force rebuilding the dependencies if needed.
+ _update_deps_oiio false true
fi
_clean
}
@@ -2016,6 +2001,9 @@ compile_OIIO() {
oiio_magic=17
_init_oiio
+ # Force having own builds for the dependencies.
+ _update_deps_oiio true false
+
# Clean install if needed!
magic_compile_check oiio-$OIIO_VERSION $oiio_magic
if [ $? -eq 1 -o "$OIIO_FORCE_REBUILD" = true ]; then
@@ -2024,10 +2012,9 @@ compile_OIIO() {
if [ ! -d $_inst ]; then
INFO "Building OpenImageIO-$OIIO_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_oiio
+ # Force rebuilding the dependencies.
+ _update_deps_oiio true true
prepare_inst
@@ -2064,7 +2051,6 @@ compile_OIIO() {
cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
- cmake_d="$cmake_d -D BUILDSTATIC=OFF"
cmake_d="$cmake_d -D LINKSTATIC=OFF"
cmake_d="$cmake_d -D USE_SIMD=sse2"
@@ -2092,16 +2078,13 @@ compile_OIIO() {
#cmake_d="$cmake_d -D CMAKE_VERBOSE_MAKEFILE=ON"
if [ -d $INST/boost ]; then
- cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON"
+ cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON -D Boost_NO_BOOST_CMAKE=ON"
fi
# Looks like we do not need ocio in oiio for now...
# if [ -d $INST/ocio ]; then
# cmake_d="$cmake_d -D OCIO_PATH=$INST/ocio"
# fi
- cmake_d="$cmake_d -D USE_OCIO=OFF"
-
- cmake_d="$cmake_d -D OIIO_BUILD_CPP11=ON"
if file /bin/cp | grep -q '32-bit'; then
cflags="-fPIC -m32 -march=i686"
@@ -2125,7 +2108,6 @@ compile_OIIO() {
cd $CWD
INFO "Done compiling OpenImageIO-$OIIO_VERSION!"
- _is_building=false
else
INFO "Own OpenImageIO-$OIIO_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-oiio option."
@@ -2147,16 +2129,19 @@ _init_llvm() {
}
_update_deps_llvm() {
- OSL_FORCE_REBUILD=true
- if [ "$_is_building" = true ]; then
+ if [ "$1" = true ]; then
OSL_FORCE_BUILD=true
fi
+ if [ "$2" = true ]; then
+ OSL_FORCE_REBUILD=true
+ fi
}
clean_LLVM() {
_init_llvm
if [ -d $_inst ]; then
- _update_deps_llvm
+ # Force rebuilding the dependencies if needed.
+ _update_deps_llvm false true
fi
_clean
}
@@ -2171,6 +2156,9 @@ compile_LLVM() {
llvm_magic=3
_init_llvm
+ # Force having own builds for the dependencies.
+ _update_deps_llvm true false
+
# Clean install if needed!
magic_compile_check llvm-$LLVM_VERSION $llvm_magic
if [ $? -eq 1 -o "$LLVM_FORCE_REBUILD" = true ]; then
@@ -2179,10 +2167,9 @@ compile_LLVM() {
if [ ! -d $_inst ]; then
INFO "Building LLVM-$LLVM_VERSION (CLANG included!)"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_llvm
+ # Force rebuilding the dependencies.
+ _update_deps_llvm true true
prepare_inst
@@ -2241,7 +2228,6 @@ compile_LLVM() {
cd $CWD
INFO "Done compiling LLVM-$LLVM_VERSION (CLANG included)!"
- _is_building=false
else
INFO "Own LLVM-$LLVM_VERSION (CLANG included) is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-llvm option."
@@ -2265,7 +2251,8 @@ _update_deps_osl() {
clean_OSL() {
_init_osl
if [ -d $_inst ]; then
- _update_deps_osl
+ # Force rebuilding the dependencies if needed.
+ _update_deps_osl false true
fi
_clean
}
@@ -2280,6 +2267,9 @@ compile_OSL() {
osl_magic=21
_init_osl
+ # Force having own builds for the dependencies.
+ _update_deps_osl true false
+
# Clean install if needed!
magic_compile_check osl-$OSL_VERSION $osl_magic
if [ $? -eq 1 -o "$OSL_FORCE_REBUILD" = true ]; then
@@ -2289,10 +2279,9 @@ compile_OSL() {
if [ ! -d $_inst ]; then
INFO "Building OpenShadingLanguage-$OSL_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_osl
+ # Force rebuilding the dependencies.
+ _update_deps_osl true true
prepare_inst
@@ -2331,7 +2320,6 @@ compile_OSL() {
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D BUILD_TESTING=OFF"
cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
- cmake_d="$cmake_d -D BUILDSTATIC=OFF"
cmake_d="$cmake_d -D OSL_BUILD_PLUGINS=OFF"
cmake_d="$cmake_d -D OSL_BUILD_TESTS=OFF"
cmake_d="$cmake_d -D USE_SIMD=sse2"
@@ -2339,6 +2327,9 @@ compile_OSL() {
cmake_d="$cmake_d -D USE_PARTIO=OFF"
cmake_d="$cmake_d -D OSL_BUILD_MATERIALX=OFF"
cmake_d="$cmake_d -D USE_QT=OFF"
+ cmake_d="$cmake_d -D USE_PYTHON=OFF"
+
+ cmake_d="$cmake_d -D CMAKE_CXX_STANDARD=14"
#~ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
@@ -2350,11 +2341,14 @@ compile_OSL() {
fi
if [ -d $INST/boost ]; then
- cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON"
+ cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON -D Boost_NO_BOOST_CMAKE=ON"
fi
if [ -d $INST/oiio ]; then
cmake_d="$cmake_d -D OPENIMAGEIO_ROOT_DIR=$INST/oiio"
+ # HACK! SIC!!!!
+ # Quiet incredible, but if root dir is given, path to lib is found, but not path to include...
+ cmake_d="$cmake_d -D OPENIMAGEIO_INCLUDE_DIR=$INST/oiio/include"
fi
if [ ! -z $LLVM_VERSION_FOUND ]; then
@@ -2384,7 +2378,6 @@ compile_OSL() {
cd $CWD
INFO "Done compiling OpenShadingLanguage-$OSL_VERSION!"
- _is_building=false
else
INFO "Own OpenShadingLanguage-$OSL_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-osl option."
@@ -2410,7 +2403,8 @@ _update_deps_osd() {
clean_OSD() {
_init_osd
if [ -d $_inst ]; then
- _update_deps_osd
+ # Force rebuilding the dependencies if needed.
+ _update_deps_osd false true
fi
_clean
}
@@ -2425,6 +2419,9 @@ compile_OSD() {
osd_magic=2
_init_osd
+ # Force having own builds for the dependencies.
+ _update_deps_osd true false
+
# Clean install if needed!
magic_compile_check osd-$OSD_VERSION $osd_magic
if [ $? -eq 1 -o "$OSD_FORCE_REBUILD" = true ]; then
@@ -2433,10 +2430,9 @@ compile_OSD() {
if [ ! -d $_inst ]; then
INFO "Building OpenSubdiv-$OSD_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_osd
+ # Force rebuilding the dependencies.
+ _update_deps_osd true true
prepare_inst
@@ -2498,7 +2494,6 @@ compile_OSD() {
cd $CWD
INFO "Done compiling OpenSubdiv-$OSD_VERSION!"
- _is_building=false
else
INFO "Own OpenSubdiv-$OSD_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-osd option."
@@ -2518,16 +2513,19 @@ _init_blosc() {
}
_update_deps_blosc() {
- OPENVDB_FORCE_REBUILD=true
- if [ "$_is_building" = true ]; then
+ if [ "$1" = true ]; then
OPENVDB_FORCE_BUILD=true
fi
+ if [ "$2" = true ]; then
+ OPENVDB_FORCE_REBUILD=true
+ fi
}
clean_BLOSC() {
_init_blosc
if [ -d $_inst ]; then
- _update_deps_blosc
+ # Force rebuilding the dependencies if needed.
+ _update_deps_blosc false true
fi
_clean
}
@@ -2542,6 +2540,9 @@ compile_BLOSC() {
blosc_magic=0
_init_blosc
+ # Force having own builds for the dependencies.
+ _update_deps_blosc true false
+
# Clean install if needed!
magic_compile_check blosc-$OPENVDB_BLOSC_VERSION $blosc_magic
if [ $? -eq 1 -o "$OPENVDB_FORCE_REBUILD" = true ]; then
@@ -2551,10 +2552,9 @@ compile_BLOSC() {
if [ ! -d $_inst ]; then
INFO "Building Blosc-$OPENVDB_BLOSC_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_blosc
+ # Force rebuilding the dependencies.
+ _update_deps_blosc true true
prepare_inst
@@ -2596,7 +2596,6 @@ compile_BLOSC() {
fi
cd $CWD
INFO "Done compiling Blosc-$OPENVDB_BLOSC_VERSION!"
- _is_building=false
else
INFO "Own Blosc-$OPENVDB_BLOSC_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib (and openvdb), use the --force-openvdb option."
@@ -2623,7 +2622,8 @@ _update_deps_nanovdb() {
clean_nanovdb() {
_init_nanovdb
if [ -d $_inst ]; then
- _update_deps_nanovdb
+ # Force rebuilding the dependencies if needed.
+ _update_deps_nanovdb false true
fi
_git=true # Mere trick to prevent clean from removing $_src...
_clean
@@ -2634,6 +2634,9 @@ install_NanoVDB() {
nanovdb_magic=1
_init_nanovdb
+ # Force having own builds for the dependencies.
+ _update_deps_nanovdb true false
+
# Clean install if needed!
magic_compile_check nanovdb-$OPENVDB_VERSION $nanovdb_magic
if [ $? -eq 1 ]; then
@@ -2642,10 +2645,9 @@ install_NanoVDB() {
if [ ! -d $_inst ]; then
INFO "Installing NanoVDB v$OPENVDB_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_nanovdb
+ # Force rebuilding the dependencies.
+ _update_deps_nanovdb true true
prepare_inst
@@ -2702,7 +2704,6 @@ install_NanoVDB() {
cd $CWD
INFO "Done compiling NanoVDB-v$OPENVDB_VERSION!"
- _is_building=false
else
INFO "Own NanoVDB-v$OPENVDB_VERSION is up to date, nothing to do!"
fi
@@ -2728,7 +2729,8 @@ _update_deps_openvdb() {
clean_OPENVDB() {
_init_openvdb
if [ -d $_inst ]; then
- _update_deps_openvdb
+ # Force rebuilding the dependencies if needed.
+ _update_deps_openvdb false true
fi
_clean
}
@@ -2746,6 +2748,9 @@ compile_OPENVDB() {
openvdb_magic=2
_init_openvdb
+ # Force having own builds for the dependencies.
+ _update_deps_openvdb true false
+
# Clean install if needed!
magic_compile_check openvdb-$OPENVDB_VERSION $openvdb_magic
if [ $? -eq 1 -o "$OPENVDB_FORCE_REBUILD" = true ]; then
@@ -2754,10 +2759,9 @@ compile_OPENVDB() {
if [ ! -d $_inst ]; then
INFO "Building OpenVDB-$OPENVDB_VERSION (with NanoVDB: $WITH_NANOVDB)"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_openvdb
+ # Force rebuilding the dependencies.
+ _update_deps_openvdb true true
prepare_inst
@@ -2802,6 +2806,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"
@@ -2832,7 +2837,6 @@ compile_OPENVDB() {
cd $CWD
INFO "Done compiling OpenVDB-$OPENVDB_VERSION!"
- _is_building=false
else
INFO "Own OpenVDB-$OPENVDB_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-openvdb option."
@@ -2862,7 +2866,8 @@ _update_deps_alembic() {
clean_ALEMBIC() {
_init_alembic
if [ -d $_inst ]; then
- _update_deps_alembic
+ # Force rebuilding the dependencies if needed.
+ _update_deps_alembic false true
fi
_clean
}
@@ -2877,6 +2882,9 @@ compile_ALEMBIC() {
alembic_magic=2
_init_alembic
+ # Force having own builds for the dependencies.
+ _update_deps_alembic true false
+
# Clean install if needed!
magic_compile_check alembic-$ALEMBIC_VERSION $alembic_magic
if [ $? -eq 1 -o "$ALEMBIC_FORCE_REBUILD" = true ]; then
@@ -2885,10 +2893,9 @@ compile_ALEMBIC() {
if [ ! -d $_inst ]; then
INFO "Building Alembic-$ALEMBIC_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_alembic
+ # Force rebuilding the dependencies.
+ _update_deps_alembic true true
prepare_inst
@@ -2943,7 +2950,6 @@ compile_ALEMBIC() {
cd $CWD
INFO "Done compiling Alembic-$ALEMBIC_VERSION!"
- _is_building=false
else
INFO "Own Alembic-$ALEMBIC_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-alembic option."
@@ -2967,7 +2973,8 @@ _update_deps_usd() {
clean_USD() {
_init_usd
if [ -d $_inst ]; then
- _update_deps_usd
+ # Force rebuilding the dependencies if needed.
+ _update_deps_usd false true
fi
_clean
}
@@ -2982,6 +2989,9 @@ compile_USD() {
usd_magic=1
_init_usd
+ # Force having own builds for the dependencies.
+ _update_deps_usd true false
+
# Clean install if needed!
magic_compile_check usd-$USD_VERSION $usd_magic
if [ $? -eq 1 -o "$USD_FORCE_REBUILD" = true ]; then
@@ -2990,10 +3000,9 @@ compile_USD() {
if [ ! -d $_inst ]; then
INFO "Building USD-$USD_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_usd
+ # Force rebuilding the dependencies.
+ _update_deps_usd true true
prepare_inst
@@ -3041,7 +3050,6 @@ compile_USD() {
cd $CWD
INFO "Done compiling USD-$USD_VERSION!"
- _is_building=false
else
INFO "Own USD-$USD_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-usd option."
@@ -3066,7 +3074,8 @@ _update_deps_collada() {
clean_OpenCOLLADA() {
_init_opencollada
if [ -d $_inst ]; then
- _update_deps_collada
+ # Force rebuilding the dependencies if needed.
+ _update_deps_collada false true
fi
_clean
}
@@ -3081,6 +3090,9 @@ compile_OpenCOLLADA() {
opencollada_magic=9
_init_opencollada
+ # Force having own builds for the dependencies.
+ _update_deps_opencollada true false
+
# Clean install if needed!
magic_compile_check opencollada-$OPENCOLLADA_VERSION $opencollada_magic
if [ $? -eq 1 -o "$OPENCOLLADA_FORCE_REBUILD" = true ]; then
@@ -3089,10 +3101,9 @@ compile_OpenCOLLADA() {
if [ ! -d $_inst ]; then
INFO "Building OpenCOLLADA-$OPENCOLLADA_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_collada
+ # Force rebuilding the dependencies.
+ _update_deps_collada true true
prepare_inst
@@ -3148,7 +3159,6 @@ compile_OpenCOLLADA() {
cd $CWD
INFO "Done compiling OpenCOLLADA-$OPENCOLLADA_VERSION!"
- _is_building=false
else
INFO "Own OpenCOLLADA-$OPENCOLLADA_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-opencollada option."
@@ -3172,7 +3182,8 @@ _update_deps_embree() {
clean_Embree() {
_init_embree
if [ -d $_inst ]; then
- _update_deps_embree
+ # Force rebuilding the dependencies if needed.
+ _update_deps_embree false true
fi
_clean
}
@@ -3187,6 +3198,9 @@ compile_Embree() {
embree_magic=10
_init_embree
+ # Force having own builds for the dependencies.
+ _update_deps_embree true false
+
# Clean install if needed!
magic_compile_check embree-$EMBREE_VERSION $embree_magic
if [ $? -eq 1 -o "$EMBREE_FORCE_REBUILD" = true ]; then
@@ -3195,10 +3209,9 @@ compile_Embree() {
if [ ! -d $_inst ]; then
INFO "Building Embree-$EMBREE_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_embree
+ # Force rebuilding the dependencies.
+ _update_deps_embree true true
prepare_inst
@@ -3261,7 +3274,6 @@ compile_Embree() {
cd $CWD
INFO "Done compiling Embree-$EMBREE_VERSION!"
- _is_building=false
else
INFO "Own Embree-$EMBREE_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-embree option."
@@ -3278,16 +3290,19 @@ _init_ispc() {
}
_update_deps_ispc() {
- OIDN_FORCE_REBUILD=true
- if [ "$_is_building" = true ]; then
+ if [ "$1" = true ]; then
OIDN_FORCE_BUILD=true
fi
+ if [ "$2" = true ]; then
+ OIDN_FORCE_REBUILD=true
+ fi
}
clean_ispc() {
_init_ispc
if [ -d $_inst ]; then
- _update_deps_ispc
+ # Force rebuilding the dependencies if needed.
+ _update_deps_ispc false true
fi
_clean
}
@@ -3297,6 +3312,9 @@ install_ISPC() {
ispc_magic=0
_init_ispc
+ # Force having own builds for the dependencies.
+ _update_deps_ispc true false
+
# Clean install if needed!
magic_compile_check ispc-$ISPC_VERSION $ispc_magic
if [ $? -eq 1 ]; then
@@ -3305,10 +3323,9 @@ install_ISPC() {
if [ ! -d $_inst ]; then
INFO "Installing Implicit SPMD Program Compiler v$ISPC_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_ispc
+ # Force rebuilding the dependencies.
+ _update_deps_ispc true true
prepare_inst
@@ -3334,7 +3351,6 @@ install_ISPC() {
cd $CWD
INFO "Done compiling ISPC-v$ISPC_VERSION!"
- _is_building=false
else
INFO "Own ISPC-v$ISPC_VERSION is up to date, nothing to do!"
fi
@@ -3358,7 +3374,8 @@ _update_deps_oidn() {
clean_oidn() {
_init_oidn
if [ -d $_inst ]; then
- _update_deps_oidn
+ # Force rebuilding the dependencies if needed.
+ _update_deps_oidn false true
fi
_clean
}
@@ -3376,6 +3393,9 @@ compile_OIDN() {
oidn_magic=9
_init_oidn
+ # Force having own builds for the dependencies.
+ _update_deps_oidn true false
+
# Clean install if needed!
magic_compile_check oidn-$OIDN_VERSION $oidn_magic
if [ $? -eq 1 -o "$OIDN_FORCE_REBUILD" = true ]; then
@@ -3384,10 +3404,9 @@ compile_OIDN() {
if [ ! -d $_inst ]; then
INFO "Building OpenImageDenoise-$OIDN_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_oidn
+ # Force rebuilding the dependencies.
+ _update_deps_oidn true true
prepare_inst
@@ -3446,7 +3465,6 @@ compile_OIDN() {
cd $CWD
INFO "Done compiling OpenImageDenoise-$OIDN_VERSION!"
- _is_building=false
else
INFO "Own OpenImageDenoise-$OIDN_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-oidn option."
@@ -3471,7 +3489,8 @@ _update_deps_ffmpeg() {
clean_FFmpeg() {
_init_ffmpeg
if [ -d $_inst ]; then
- _update_deps_ffmpeg
+ # Force rebuilding the dependencies if needed.
+ _update_deps_ffmpeg false true
fi
_clean
}
@@ -3486,6 +3505,9 @@ compile_FFmpeg() {
ffmpeg_magic=5
_init_ffmpeg
+ # Force having own builds for the dependencies.
+ _update_deps_ffmpeg true false
+
# Clean install if needed!
magic_compile_check ffmpeg-$FFMPEG_VERSION $ffmpeg_magic
if [ $? -eq 1 -o "$FFMPEG_FORCE_REBUILD" = true ]; then
@@ -3494,10 +3516,9 @@ compile_FFmpeg() {
if [ ! -d $_inst ]; then
INFO "Building ffmpeg-$FFMPEG_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_ffmpeg
+ # Force rebuilding the dependencies.
+ _update_deps_ffmpeg true true
prepare_inst
@@ -3576,7 +3597,6 @@ compile_FFmpeg() {
cd $CWD
INFO "Done compiling ffmpeg-$FFMPEG_VERSION!"
- _is_building=false
else
INFO "Own ffmpeg-$FFMPEG_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-ffmpeg option."
@@ -3600,7 +3620,8 @@ _update_deps_xr_openxr_sdk() {
clean_XR_OpenXR_SDK() {
_init_xr_openxr_sdk
if [ -d $_inst ]; then
- _update_deps_xr_openxr_sdk
+ # Force rebuilding the dependencies if needed.
+ _update_deps_xr_openxr_sdk false true
fi
_clean
}
@@ -3615,6 +3636,9 @@ compile_XR_OpenXR_SDK() {
xr_openxr_magic=2
_init_xr_openxr_sdk
+ # Force having own builds for the dependencies.
+ _update_deps_xr_openxr_sdk true false
+
# Clean install if needed!
magic_compile_check xr-openxr-$XR_OPENXR_VERSION $xr_openxr_magic
if [ $? -eq 1 -o "$XR_OPENXR_FORCE_REBUILD" = true ]; then
@@ -3623,10 +3647,9 @@ compile_XR_OpenXR_SDK() {
if [ ! -d $_inst ]; then
INFO "Building XR-OpenXR-SDK-$XR_OPENXR_VERSION"
- _is_building=true
- # Rebuild dependencies as well!
- _update_deps_xr_openxr_sdk
+ # Force rebuilding the dependencies.
+ _update_deps_xr_openxr_sdk true true
prepare_inst
@@ -3687,7 +3710,6 @@ compile_XR_OpenXR_SDK() {
cd $CWD
INFO "Done compiling XR-OpenXR-SDK-$XR_OPENXR_VERSION!"
- _is_building=false
else
INFO "Own XR-OpenXR-SDK-$XR_OPENXR_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-xr-openxr option."
@@ -3798,7 +3820,7 @@ install_DEB() {
libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev \
libopenal-dev libglew-dev yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV \
libsdl2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev \
- libgmp-dev libpugixml-dev libpotrace-dev"
+ libgmp-dev libpugixml-dev libpotrace-dev libhpdf-dev"
# libglewmx-dev (broken in deb testing currently...)
VORBIS_USE=true
@@ -3949,9 +3971,9 @@ install_DEB() {
PRINT ""
_do_compile_python=false
if [ "$PYTHON_SKIP" = true ]; then
- WARNING "Skipping Python/NumPy installation, as requested..."
+ WARNING "Skipping Python installation, as requested..."
elif [ "$PYTHON_FORCE_BUILD" = true ]; then
- INFO "Forced Python/NumPy building, as requested..."
+ INFO "Forced Python building, as requested..."
_do_compile_python=true
else
check_package_version_ge_lt_DEB python3-dev $PYTHON_VERSION_MIN $PYTHON_VERSION_MAX
@@ -3961,17 +3983,21 @@ install_DEB() {
install_packages_DEB python3-dev
clean_Python
PRINT ""
- if [ "$NUMPY_SKIP" = true ]; then
- WARNING "Skipping NumPy installation, as requested..."
- else
- check_package_DEB python3-numpy
+
+ for module in "${PYTHON_MODULES_PACKAGES[@]}"
+ do
+ module=($module)
+ package="python3-${module[0]}"
+ package_vmin=${module[1]}
+ package_vmax=${module[2]}
+ check_package_version_ge_lt_DEB "$package" $package_vmin $package_vmax
if [ $? -eq 0 ]; then
- install_packages_DEB python3-numpy
+ install_packages_DEB "$package"
else
- WARNING "Sorry, using python package but no valid numpy package available!" \
- " Use --build-numpy to force building of both Python and NumPy."
+ WARNING "Sorry, using python package but no valid $package package available!" \
+ " Use --build-python to force building of Python and use pip to get the packages."
fi
- fi
+ done
else
_do_compile_python=true
fi
@@ -3980,12 +4006,6 @@ install_DEB() {
if $_do_compile_python; then
install_packages_DEB libffi-dev
compile_Python
- PRINT ""
- if [ "$NUMPY_SKIP" = true ]; then
- WARNING "Skipping NumPy installation, as requested..."
- else
- compile_Numpy
- fi
fi
@@ -4092,7 +4112,7 @@ install_DEB() {
else
check_package_version_ge_lt_DEB llvm-dev $LLVM_VERSION_MIN $LLVM_VERSION_MAX
if [ $? -eq 0 ]; then
- install_packages_DEB llvm-dev clang
+ install_packages_DEB llvm-dev clang libclang-dev
have_llvm=true
LLVM_VERSION=`llvm-config --version`
LLVM_VERSION_FOUND=$LLVM_VERSION
@@ -4465,7 +4485,7 @@ install_RPM() {
wget ncurses-devel readline-devel $OPENJPEG_DEV openal-soft-devel \
glew-devel yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV patch \
libxml2-devel yaml-cpp-devel tinyxml-devel jemalloc-devel \
- gmp-devel pugixml-devel potrace-devel"
+ gmp-devel pugixml-devel potrace-devel libharu-devel"
OPENJPEG_USE=true
VORBIS_USE=true
@@ -4585,7 +4605,7 @@ install_RPM() {
if [ "$PYTHON_SKIP" = true ]; then
WARNING "Skipping Python installation, as requested..."
elif [ "$PYTHON_FORCE_BUILD" = true ]; then
- INFO "Forced Python/NumPy building, as requested..."
+ INFO "Forced Python building, as requested..."
_do_compile_python=true
else
check_package_version_ge_lt_RPM python3-devel $PYTHON_VERSION_MIN $PYTHON_VERSION_MAX
@@ -4594,18 +4614,21 @@ install_RPM() {
install_packages_RPM python3-devel
clean_Python
- PRINT ""
- if [ "$NUMPY_SKIP" = true ]; then
- WARNING "Skipping NumPy installation, as requested..."
- else
- check_package_version_ge_lt_RPM python3-numpy $NUMPY_VERSION_MIN $NUMPY_VERSION_MAX
+
+ for module in "${PYTHON_MODULES_PACKAGES[@]}"
+ do
+ module=($module)
+ package="python3-${module[0]}"
+ package_vmin=${module[1]}
+ package_vmax=${module[2]}
+ check_package_version_ge_lt_RPM "$package" $package_vmin $package_vmax
if [ $? -eq 0 ]; then
- install_packages_RPM python3-numpy
+ install_packages_RPM "$package"
else
- WARNING "Sorry, using python package but no valid numpy package available!" \
- " Use --build-numpy to force building of both Python and NumPy."
+ WARNING "Sorry, using python package but no valid $package package available!" \
+ " Use --build-python to force building of Python and use pip to get the packages."
fi
- fi
+ done
else
_do_compile_python=true
fi
@@ -4614,12 +4637,6 @@ install_RPM() {
if [ "$_do_compile_python" = true ]; then
install_packages_RPM libffi-devel
compile_Python
- PRINT ""
- if [ "$NUMPY_SKIP" = true ]; then
- WARNING "Skipping NumPy installation, as requested..."
- else
- compile_Numpy
- fi
fi
@@ -5041,7 +5058,7 @@ install_ARCH() {
_packages="$BASE_DEVEL git cmake fontconfig \
libxi libxcursor libxrandr libxinerama glew libpng libtiff wget openal \
$OPENJPEG_DEV $VORBIS_DEV $OGG_DEV $THEORA_DEV yasm sdl2 fftw \
- libxml2 yaml-cpp tinyxml python-requests jemalloc gmp potrace pugixml"
+ libxml2 yaml-cpp tinyxml python-requests jemalloc gmp potrace pugixml libharu"
OPENJPEG_USE=true
VORBIS_USE=true
@@ -5126,7 +5143,7 @@ install_ARCH() {
if [ "$PYTHON_SKIP" = true ]; then
WARNING "Skipping Python installation, as requested..."
elif [ "$PYTHON_FORCE_BUILD" = true ]; then
- INFO "Forced Python/NumPy building, as requested..."
+ INFO "Forced Python building, as requested..."
_do_compile_python=true
else
check_package_version_ge_lt_ARCH python $PYTHON_VERSION_MIN $PYTHON_VERSION_MAX
@@ -5136,17 +5153,21 @@ install_ARCH() {
install_packages_ARCH python
clean_Python
PRINT ""
- if [ "$NUMPY_SKIP" = true ]; then
- WARNING "Skipping NumPy installation, as requested..."
- else
- check_package_version_ge_ARCH python-numpy $NUMPY_VERSION_MIN $NUMPY_VERSION_MAX
+
+ for module in "${PYTHON_MODULES_PACKAGES[@]}"
+ do
+ module=($module)
+ package="python-${module[0]}"
+ package_vmin=${module[1]}
+ package_vmax=${module[2]}
+ check_package_version_ge_lt_ARCH "$package" $package_vmin $package_vmax
if [ $? -eq 0 ]; then
- install_packages_ARCH python-numpy
+ install_packages_ARCH "$package"
else
- WARNING "Sorry, using python package but no valid numpy package available!" \
- "Use --build-numpy to force building of both Python and NumPy."
+ WARNING "Sorry, using python package but no valid $package package available!" \
+ " Use --build-python to force building of Python and use pip to get the packages."
fi
- fi
+ done
else
_do_compile_python=true
fi
@@ -5155,12 +5176,6 @@ install_ARCH() {
if [ "$_do_compile_python" = true ]; then
install_packages_ARCH libffi
compile_Python
- PRINT ""
- if [ "$NUMPY_SKIP" = true ]; then
- WARNING "Skipping NumPy installation, as requested..."
- else
- compile_Numpy
- fi
fi
@@ -5493,16 +5508,10 @@ install_OTHER() {
PRINT ""
if [ "$PYTHON_SKIP" = true ]; then
- WARNING "Skipping Python/NumPy installation, as requested..."
+ WARNING "Skipping Python installation, as requested..."
elif [ "$PYTHON_FORCE_BUILD" = true ]; then
- INFO "Forced Python/NumPy building, as requested..."
+ INFO "Forced Python building, as requested..."
compile_Python
- PRINT ""
- if [ "$NUMPY_SKIP" = true ]; then
- WARNING "Skipping NumPy installation, as requested..."
- else
- compile_Numpy
- fi
fi
@@ -5736,9 +5745,11 @@ print_info() {
if [ -d $INST/boost ]; then
_1="-D BOOST_ROOT=$INST/boost"
_2="-D Boost_NO_SYSTEM_PATHS=ON"
+ _3="-D Boost_NO_BOOST_CMAKE=ON"
PRINT " $_1"
PRINT " $_2"
- _buildargs="$_buildargs $_1 $_2"
+ PRINT " $_3"
+ _buildargs="$_buildargs $_1 $_2 $_3"
fi
if [ -d $INST/tbb ]; then
diff --git a/build_files/build_environment/patches/haru.diff b/build_files/build_environment/patches/haru.diff
new file mode 100644
index 00000000000..fed551b4bf0
--- /dev/null
+++ b/build_files/build_environment/patches/haru.diff
@@ -0,0 +1,12 @@
+diff --git a/src/hpdf_image_ccitt.c b/src/hpdf_image_ccitt.c
+index 8672763..9be531a 100644
+--- a/src/hpdf_image_ccitt.c
++++ b/src/hpdf_image_ccitt.c
+@@ -21,7 +21,6 @@
+ #include <memory.h>
+ #include <assert.h>
+
+-#define G3CODES
+ #include "t4.h"
+
+ typedef unsigned int uint32;
diff --git a/build_files/build_environment/patches/python_linux.diff b/build_files/build_environment/patches/python_linux.diff
index 24d625c7ceb..a9baae8ce32 100644
--- a/build_files/build_environment/patches/python_linux.diff
+++ b/build_files/build_environment/patches/python_linux.diff
@@ -2,23 +2,23 @@ diff --git a/setup.py.orig b/setup.py
index a97a755..07ce853 100644
--- a/setup.py.orig
+++ b/setup.py
-@@ -1422,13 +1422,13 @@ class PyBuildExt(build_ext):
+@@ -1603,13 +1603,13 @@
version = line.split()[2]
break
if version >= version_req:
-- if (self.compiler.find_library_file(lib_dirs, 'z')):
-+ if (self.compiler.find_library_file(lib_dirs, 'z_pic')):
- if host_platform == "darwin":
+- if (self.compiler.find_library_file(self.lib_dirs, 'z')):
++ if (self.compiler.find_library_file(self.lib_dirs, 'z_pic')):
+ if MACOS:
zlib_extra_link_args = ('-Wl,-search_paths_first',)
else:
zlib_extra_link_args = ()
- exts.append( Extension('zlib', ['zlibmodule.c'],
-- libraries = ['z'],
-+ libraries = ['z_pic'],
- extra_link_args = zlib_extra_link_args))
+ self.add(Extension('zlib', ['zlibmodule.c'],
+- libraries=['z'],
++ libraries=['z_pic'],
+ extra_link_args=zlib_extra_link_args))
have_zlib = True
else:
-@@ -1442,7 +1442,7 @@ class PyBuildExt(build_ext):
+@@ -1623,7 +1623,7 @@
# crc32 if we have it. Otherwise binascii uses its own.
if have_zlib:
extra_compile_args = ['-DUSE_ZLIB_CRC32']
@@ -27,12 +27,12 @@ index a97a755..07ce853 100644
extra_link_args = zlib_extra_link_args
else:
extra_compile_args = []
-@@ -1991,7 +1991,7 @@ class PyBuildExt(build_ext):
+@@ -2168,7 +2168,7 @@
+ ffi_inc = None
print('Header file {} does not exist'.format(ffi_h))
- ffi_lib = None
- if ffi_inc is not None:
+ if ffi_lib is None and ffi_inc:
- for lib_name in ('ffi', 'ffi_pic'):
+ for lib_name in ('ffi_pic', ):
- if (self.compiler.find_library_file(lib_dirs, lib_name)):
+ if (self.compiler.find_library_file(self.lib_dirs, lib_name)):
ffi_lib = lib_name
break
diff --git a/build_files/build_environment/patches/python_macos.diff b/build_files/build_environment/patches/python_macos.diff
deleted file mode 100644
index 22ccbebee2f..00000000000
--- a/build_files/build_environment/patches/python_macos.diff
+++ /dev/null
@@ -1,289 +0,0 @@
-diff -ru a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
---- a/Doc/library/ctypes.rst 2020-03-10 07:11:12.000000000 +0100
-+++ b/Doc/library/ctypes.rst 2020-07-14 08:10:10.000000000 +0200
-@@ -1551,6 +1551,13 @@
- value usable as argument (integer, string, ctypes instance). This allows
- defining adapters that can adapt custom objects as function parameters.
-
-+ .. attribute:: variadic
-+
-+ Assign a boolean to specify that the function takes a variable number of
-+ arguments. This does not matter on most platforms, but for Apple arm64
-+ platforms variadic functions have a different calling convention than
-+ normal functions.
-+
- .. attribute:: errcheck
-
- Assign a Python function or another callable to this attribute. The
-diff -ru a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
---- a/Modules/_ctypes/_ctypes.c 2020-03-10 07:11:12.000000000 +0100
-+++ b/Modules/_ctypes/_ctypes.c 2020-07-14 08:14:41.000000000 +0200
-@@ -3175,6 +3175,35 @@
- }
-
- static int
-+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
-+{
-+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
-+ assert(dict);
-+ int r = PyObject_IsTrue(ob);
-+ if (r == 1) {
-+ dict->flags |= FUNCFLAG_VARIADIC;
-+ return 0;
-+ } else if (r == 0) {
-+ dict->flags &= ~FUNCFLAG_VARIADIC;
-+ return 0;
-+ } else {
-+ return -1;
-+ }
-+}
-+
-+static PyObject *
-+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
-+{
-+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
-+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
-+ if (dict->flags & FUNCFLAG_VARIADIC)
-+ Py_RETURN_TRUE;
-+ else
-+ Py_RETURN_FALSE;
-+}
-+
-+
-+static int
- PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
- {
- PyObject *converters;
-@@ -5632,6 +5661,7 @@
- PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
- PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
- PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
-+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyLong_FromLong(FUNCFLAG_VARIADIC));
- PyModule_AddStringConstant(m, "__version__", "1.1.0");
-
- PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
-diff -ru a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
---- a/Modules/_ctypes/callproc.c 2020-03-10 07:11:12.000000000 +0100
-+++ b/Modules/_ctypes/callproc.c 2020-07-14 08:18:33.000000000 +0200
-@@ -767,7 +767,8 @@
- ffi_type **atypes,
- ffi_type *restype,
- void *resmem,
-- int argcount)
-+ int argcount,
-+ int argtypecount)
- {
- PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
- PyObject *error_object = NULL;
-@@ -793,15 +794,38 @@
- if ((flags & FUNCFLAG_CDECL) == 0)
- cc = FFI_STDCALL;
- #endif
-- if (FFI_OK != ffi_prep_cif(&cif,
-- cc,
-- argcount,
-- restype,
-- atypes)) {
-- PyErr_SetString(PyExc_RuntimeError,
-- "ffi_prep_cif failed");
-- return -1;
-- }
-+#if HAVE_FFI_PREP_CIF_VAR
-+ /* Everyone SHOULD set f.variadic=True on variadic function pointers, but
-+ * lots of existing code will not. If there's at least one arg and more
-+ * args are passed than are defined in the prototype, then it must be a
-+ * variadic function. */
-+ if ((flags & FUNCFLAG_VARIADIC) ||
-+ (argtypecount != 0 && argcount > argtypecount))
-+ {
-+ if (FFI_OK != ffi_prep_cif_var(&cif,
-+ cc,
-+ argtypecount,
-+ argcount,
-+ restype,
-+ atypes)) {
-+ PyErr_SetString(PyExc_RuntimeError,
-+ "ffi_prep_cif_var failed");
-+ return -1;
-+ }
-+ } else {
-+#endif
-+ if (FFI_OK != ffi_prep_cif(&cif,
-+ cc,
-+ argcount,
-+ restype,
-+ atypes)) {
-+ PyErr_SetString(PyExc_RuntimeError,
-+ "ffi_prep_cif failed");
-+ return -1;
-+ }
-+#if HAVE_FFI_PREP_CIF_VAR
-+ }
-+#endif
-
- if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
- error_object = _ctypes_get_errobj(&space);
-@@ -1185,9 +1209,8 @@
-
- if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
- rtype, resbuf,
-- Py_SAFE_DOWNCAST(argcount,
-- Py_ssize_t,
-- int)))
-+ Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int),
-+ Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
- goto cleanup;
-
- #ifdef WORDS_BIGENDIAN
-diff -ru a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
---- a/Modules/_ctypes/ctypes.h 2020-03-10 07:11:12.000000000 +0100
-+++ b/Modules/_ctypes/ctypes.h 2020-07-14 08:30:53.000000000 +0200
-@@ -285,6 +285,7 @@
- #define FUNCFLAG_PYTHONAPI 0x4
- #define FUNCFLAG_USE_ERRNO 0x8
- #define FUNCFLAG_USE_LASTERROR 0x10
-+#define FUNCFLAG_VARIADIC 0x20
-
- #define TYPEFLAG_ISPOINTER 0x100
- #define TYPEFLAG_HASPOINTER 0x200
-diff -ru a/configure b/configure
---- a/configure 2020-03-10 07:11:12.000000000 +0100
-+++ b/configure 2020-07-14 08:03:27.000000000 +0200
-@@ -3374,7 +3374,7 @@
- # has no effect, don't bother defining them
- Darwin/[6789].*)
- define_xopen_source=no;;
-- Darwin/1[0-9].*)
-+ Darwin/[12][0-9].*)
- define_xopen_source=no;;
- # On AIX 4 and 5.1, mbstate_t is defined only when _XOPEN_SOURCE == 500 but
- # used in wcsnrtombs() and mbsnrtowcs() even if _XOPEN_SOURCE is not defined
-@@ -9251,6 +9251,9 @@
- ppc)
- MACOSX_DEFAULT_ARCH="ppc64"
- ;;
-+ arm64)
-+ MACOSX_DEFAULT_ARCH="arm64"
-+ ;;
- *)
- as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
- ;;
-diff -ru a/configure.ac b/configure.ac
---- a/configure.ac 2020-03-10 07:11:12.000000000 +0100
-+++ b/configure.ac 2020-07-14 08:03:27.000000000 +0200
-@@ -2456,6 +2456,9 @@
- ppc)
- MACOSX_DEFAULT_ARCH="ppc64"
- ;;
-+ arm64)
-+ MACOSX_DEFAULT_ARCH="arm64"
-+ ;;
- *)
- AC_MSG_ERROR([Unexpected output of 'arch' on OSX])
- ;;
-diff -ru a/setup.py b/setup.py
---- a/setup.py 2020-03-10 07:11:12.000000000 +0100
-+++ b/setup.py 2020-07-14 08:28:12.000000000 +0200
-@@ -141,6 +141,13 @@
- os.unlink(tmpfile)
-
- return MACOS_SDK_ROOT
-+
-+def is_macosx_at_least(vers):
-+ if host_platform == 'darwin':
-+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
-+ if dep_target:
-+ return tuple(map(int, dep_target.split('.'))) >= vers
-+ return False
-
- def is_macosx_sdk_path(path):
- """
-@@ -150,6 +157,13 @@
- or path.startswith('/System/')
- or path.startswith('/Library/') )
-
-+def grep_headers_for(function, headers):
-+ for header in headers:
-+ with open(header, 'r') as f:
-+ if function in f.read():
-+ return True
-+ return False
-+
- def find_file(filename, std_dirs, paths):
- """Searches for the directory where a given file is located,
- and returns a possibly-empty list of additional directories, or None
-@@ -1972,7 +1986,11 @@
- return True
-
- def detect_ctypes(self, inc_dirs, lib_dirs):
-- self.use_system_libffi = False
-+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
-+ self.use_system_libffi = True
-+ else:
-+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
-+
- include_dirs = []
- extra_compile_args = []
- extra_link_args = []
-@@ -2016,32 +2034,48 @@
- ext_test = Extension('_ctypes_test',
- sources=['_ctypes/_ctypes_test.c'],
- libraries=['m'])
-+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
-+ ffi_lib = None
-+
- self.extensions.extend([ext, ext_test])
-
- if host_platform == 'darwin':
-- if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
-+ if not self.use_system_libffi:
- return
-- # OS X 10.5 comes with libffi.dylib; the include files are
-- # in /usr/include/ffi
-- inc_dirs.append('/usr/include/ffi')
--
-- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
-- if not ffi_inc or ffi_inc[0] == '':
-- ffi_inc = find_file('ffi.h', [], inc_dirs)
-- if ffi_inc is not None:
-- ffi_h = ffi_inc[0] + '/ffi.h'
-+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
-+ if os.path.exists(ffi_in_sdk):
-+ ffi_inc = ffi_in_sdk
-+ ffi_lib = 'ffi'
-+ else:
-+ # OS X 10.5 comes with libffi.dylib; the include files are
-+ # in /usr/include/ffi
-+ ffi_inc_dirs.append('/usr/include/ffi')
-+
-+ if not ffi_inc:
-+ found = find_file('ffi.h', [], ffi_inc_dirs)
-+ if found:
-+ ffi_inc = found[0]
-+ if ffi_inc:
-+ ffi_h = ffi_inc + '/ffi.h'
- if not os.path.exists(ffi_h):
- ffi_inc = None
- print('Header file {} does not exist'.format(ffi_h))
-- ffi_lib = None
-- if ffi_inc is not None:
-+ if ffi_lib is None and ffi_inc:
- for lib_name in ('ffi', 'ffi_pic'):
- if (self.compiler.find_library_file(lib_dirs, lib_name)):
- ffi_lib = lib_name
- break
-
- if ffi_inc and ffi_lib:
-- ext.include_dirs.extend(ffi_inc)
-+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
-+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
-+ try:
-+ sources.remove('_ctypes/malloc_closure.c')
-+ except ValueError:
-+ pass
-+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
-+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
-+ ext.include_dirs.append(ffi_inc)
- ext.libraries.append(ffi_lib)
- self.use_system_libffi = True
-
diff --git a/build_files/cmake/Modules/FindAudaspace.cmake b/build_files/cmake/Modules/FindAudaspace.cmake
index 07ce2ba33d0..d4a68461d32 100644
--- a/build_files/cmake/Modules/FindAudaspace.cmake
+++ b/build_files/cmake/Modules/FindAudaspace.cmake
@@ -19,7 +19,7 @@
#=============================================================================
IF(NOT AUDASPACE_ROOT_DIR AND NOT $ENV{AUDASPACE_ROOT_DIR} STREQUAL "")
- SET(AUDASPACE_ROOT_DIR $ENV{AUDASPACE_ROOT_DIR})
+ SET(AUDASPACE_ROOT_DIR $ENV{AUDASPACE_ROOT_DIR})
ENDIF()
SET(_audaspace_SEARCH_DIRS
diff --git a/build_files/cmake/Modules/FindClangTidy.cmake b/build_files/cmake/Modules/FindClangTidy.cmake
index 04c5dfda448..4cf416e67d7 100644
--- a/build_files/cmake/Modules/FindClangTidy.cmake
+++ b/build_files/cmake/Modules/FindClangTidy.cmake
@@ -34,6 +34,8 @@ set(_clang_tidy_SEARCH_DIRS
# TODO(sergey): Find more reliable way of finding the latest clang-tidy.
find_program(CLANG_TIDY_EXECUTABLE
NAMES
+ clang-tidy-12
+ clang-tidy-11
clang-tidy-10
clang-tidy-9
clang-tidy-8
diff --git a/build_files/cmake/Modules/FindEmbree.cmake b/build_files/cmake/Modules/FindEmbree.cmake
index 0716f47ca52..af545cee00c 100644
--- a/build_files/cmake/Modules/FindEmbree.cmake
+++ b/build_files/cmake/Modules/FindEmbree.cmake
@@ -59,14 +59,14 @@ FOREACH(COMPONENT ${_embree_FIND_COMPONENTS})
PATH_SUFFIXES
lib64 lib
)
- IF (NOT EMBREE_${UPPERCOMPONENT}_LIBRARY)
- IF (EMBREE_EMBREE3_LIBRARY)
+ IF(NOT EMBREE_${UPPERCOMPONENT}_LIBRARY)
+ IF(EMBREE_EMBREE3_LIBRARY)
# If we can't find all the static libraries, try to fall back to the shared library if found.
# This allows building with a shared embree library
SET(_embree_LIBRARIES ${EMBREE_EMBREE3_LIBRARY})
BREAK()
- ENDIF ()
- ENDIF ()
+ ENDIF()
+ ENDIF()
LIST(APPEND _embree_LIBRARIES "${EMBREE_${UPPERCOMPONENT}_LIBRARY}")
ENDFOREACH()
diff --git a/build_files/cmake/Modules/FindHaru.cmake b/build_files/cmake/Modules/FindHaru.cmake
new file mode 100644
index 00000000000..5774f83b8c5
--- /dev/null
+++ b/build_files/cmake/Modules/FindHaru.cmake
@@ -0,0 +1,64 @@
+# - Find HARU library
+# Find the native Haru includes and library
+# This module defines
+# HARU_INCLUDE_DIRS, where to find hpdf.h, set when
+# HARU_INCLUDE_DIR is found.
+# HARU_LIBRARIES, libraries to link against to use Haru.
+# HARU_ROOT_DIR, The base directory to search for Haru.
+# This can also be an environment variable.
+# HARU_FOUND, If false, do not try to use Haru.
+#
+# also defined, but not for general use are
+# HARU_LIBRARY, where to find the Haru library.
+
+#=============================================================================
+# Copyright 2021 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD 3-Clause License,
+# see accompanying file BSD-3-Clause-license.txt for details.
+#=============================================================================
+
+# If HARU_ROOT_DIR was defined in the environment, use it.
+if(NOT HARU_ROOT_DIR AND NOT $ENV{HARU_ROOT_DIR} STREQUAL "")
+ set(HARU_ROOT_DIR $ENV{HARU_ROOT_DIR})
+endif()
+
+set(_haru_SEARCH_DIRS
+ ${HARU_ROOT_DIR}
+ /opt/lib/haru
+)
+
+find_path(HARU_INCLUDE_DIR
+ NAMES
+ hpdf.h
+ HINTS
+ ${_haru_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include/haru
+)
+
+find_library(HARU_LIBRARY
+ NAMES
+ hpdfs
+ HINTS
+ ${_haru_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+)
+
+# Handle the QUIETLY and REQUIRED arguments and set HARU_FOUND to TRUE if
+# all listed variables are TRUE.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Haru DEFAULT_MSG HARU_LIBRARY HARU_INCLUDE_DIR)
+
+if(HARU_FOUND)
+ set(HARU_LIBRARIES ${HARU_LIBRARY})
+ set(HARU_INCLUDE_DIRS ${HARU_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(
+ HARU_INCLUDE_DIR
+ HARU_LIBRARY
+)
+
+unset(_haru_SEARCH_DIRS)
diff --git a/build_files/cmake/Modules/GTest.cmake b/build_files/cmake/Modules/GTest.cmake
index d32e49d2145..4faa47452b1 100644
--- a/build_files/cmake/Modules/GTest.cmake
+++ b/build_files/cmake/Modules/GTest.cmake
@@ -272,7 +272,7 @@ cmake_policy(SET CMP0057 NEW) # if IN_LIST
#------------------------------------------------------------------------------
function(gtest_add_tests)
- if (ARGC LESS 1)
+ if(ARGC LESS 1)
message(FATAL_ERROR "No arguments supplied to gtest_add_tests()")
endif()
@@ -298,7 +298,7 @@ function(gtest_add_tests)
set(autoAddSources YES)
else()
# Non-keyword syntax, convert to keyword form
- if (ARGC LESS 3)
+ if(ARGC LESS 3)
message(FATAL_ERROR "gtest_add_tests() without keyword options requires at least 3 arguments")
endif()
set(ARGS_TARGET "${ARGV0}")
diff --git a/build_files/cmake/Modules/GTestTesting.cmake b/build_files/cmake/Modules/GTestTesting.cmake
index 70f48fc33ea..0c78111eaaf 100644
--- a/build_files/cmake/Modules/GTestTesting.cmake
+++ b/build_files/cmake/Modules/GTestTesting.cmake
@@ -99,7 +99,9 @@ macro(BLENDER_SRC_GTEST_EX)
# Don't fail tests on leaks since these often happen in external libraries
# that we can't fix.
- set_tests_properties(${TARGET_NAME} PROPERTIES ENVIRONMENT LSAN_OPTIONS=exitcode=0)
+ set_tests_properties(${TARGET_NAME} PROPERTIES
+ ENVIRONMENT LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS}
+ )
endif()
if(WIN32)
set_target_properties(${TARGET_NAME} PROPERTIES VS_GLOBAL_VcpkgEnabled "false")
diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake
index aab997ab453..75f78befb60 100644
--- a/build_files/cmake/config/blender_full.cmake
+++ b/build_files/cmake/config/blender_full.cmake
@@ -19,6 +19,7 @@ set(WITH_DRACO ON CACHE BOOL "" FORCE)
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
set(WITH_GMP ON CACHE BOOL "" FORCE)
+set(WITH_HARU ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake
index 480548abca7..680734aba6e 100644
--- a/build_files/cmake/config/blender_lite.cmake
+++ b/build_files/cmake/config/blender_lite.cmake
@@ -24,6 +24,7 @@ set(WITH_DRACO OFF CACHE BOOL "" FORCE)
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
set(WITH_GMP OFF CACHE BOOL "" FORCE)
+set(WITH_HARU OFF CACHE BOOL "" FORCE)
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake
index 96101ee7bcc..973d6cdb34e 100644
--- a/build_files/cmake/config/blender_release.cmake
+++ b/build_files/cmake/config/blender_release.cmake
@@ -20,6 +20,7 @@ set(WITH_DRACO ON CACHE BOOL "" FORCE)
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
set(WITH_GMP ON CACHE BOOL "" FORCE)
+set(WITH_HARU ON CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index d1f51b99c67..aebcd25e3b6 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -389,7 +389,7 @@ function(blender_add_lib
endfunction()
function(blender_add_test_suite)
- if (ARGC LESS 1)
+ if(ARGC LESS 1)
message(FATAL_ERROR "No arguments supplied to blender_add_test_suite()")
endif()
@@ -1209,9 +1209,9 @@ function(find_python_package
site-packages
dist-packages
vendor-packages
- NO_DEFAULT_PATH
- DOC
- "Path to python site-packages or dist-packages containing '${package}' module"
+ NO_DEFAULT_PATH
+ DOC
+ "Path to python site-packages or dist-packages containing '${package}' module"
)
mark_as_advanced(PYTHON_${_upper_package}_PATH)
diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake
index 31da5292eaf..8a7792bd886 100644
--- a/build_files/cmake/platform/platform_apple.cmake
+++ b/build_files/cmake/platform/platform_apple.cmake
@@ -72,7 +72,11 @@ if(WITH_JACK)
endif()
if(NOT DEFINED LIBDIR)
- set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
+ if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")
+ set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
+ else()
+ set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin_${CMAKE_OSX_ARCHITECTURES})
+ endif()
else()
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
endif()
@@ -428,6 +432,14 @@ if(WITH_GMP)
endif()
endif()
+if(WITH_HARU)
+ find_package(Haru)
+ if(NOT HARU_FOUND)
+ message(WARNING "Haru not found, disabling WITH_HARU")
+ set(WITH_HARU OFF)
+ endif()
+endif()
+
if(EXISTS ${LIBDIR})
without_system_libs_end()
endif()
diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index a2448829206..fed70c5b8b2 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -353,7 +353,7 @@ endif()
if(WITH_PUGIXML)
find_package_wrapper(PugiXML)
- if (NOT PUGIXML_FOUND)
+ if(NOT PUGIXML_FOUND)
set(WITH_PUGIXML OFF)
message(STATUS "PugiXML not found, disabling WITH_PUGIXML")
endif()
@@ -470,6 +470,14 @@ if(WITH_POTRACE)
endif()
endif()
+if(WITH_HARU)
+ find_package_wrapper(Haru)
+ if(NOT HARU_FOUND)
+ message(WARNING "Haru not found, disabling WITH_HARU")
+ set(WITH_HARU OFF)
+ endif()
+endif()
+
if(EXISTS ${LIBDIR})
without_system_libs_end()
endif()
diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake
index 016ae58fde4..69a78ba7ca6 100644
--- a/build_files/cmake/platform/platform_win32.cmake
+++ b/build_files/cmake/platform/platform_win32.cmake
@@ -800,3 +800,15 @@ if(WITH_POTRACE)
set(POTRACE_LIBRARIES ${LIBDIR}/potrace/lib/potrace.lib)
set(POTRACE_FOUND On)
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)
+ else()
+ message(WARNING "Haru was not found, disabling WITH_HARU")
+ set(WITH_HARU OFF)
+ endif()
+endif()
diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py
index 53f6b3d447f..2b8c7af98fb 100755
--- a/build_files/utils/make_update.py
+++ b/build_files/utils/make_update.py
@@ -8,6 +8,7 @@
import argparse
import os
+import platform
import shutil
import sys
@@ -49,7 +50,12 @@ def svn_update(args, release_version):
# Checkout precompiled libraries
if sys.platform == 'darwin':
- lib_platform = "darwin"
+ if platform.machine() == 'x86_64':
+ lib_platform = "darwin"
+ elif platform.machine() == 'arm64':
+ lib_platform = "darwin_arm64"
+ else:
+ lib_platform = None
elif sys.platform == 'win32':
# Windows checkout is usually handled by bat scripts since python3 to run
# this script is bundled as part of the precompiled libraries. However it
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index 772fac56f63..f9055f02bcf 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 = "V2.92"
+PROJECT_NUMBER = "V2.93"
# 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 da83abe8442..150548072d5 100755
--- a/doc/manpage/blender.1.py
+++ b/doc/manpage/blender.1.py
@@ -52,10 +52,11 @@ outfilename = sys.argv[2]
cmd = [blender_bin, "--help"]
print(" executing:", " ".join(cmd))
+ASAN_OPTIONS = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "")
blender_help = subprocess.run(
- cmd, env={"ASAN_OPTIONS": "exitcode=0"}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
+ cmd, env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
blender_version = subprocess.run(
- [blender_bin, "--version"], env={"ASAN_OPTIONS": "exitcode=0"}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8").strip()
+ [blender_bin, "--version"], env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8").strip()
blender_version, blender_date = (blender_version.split("build") + [None, None])[0:2]
blender_version = blender_version.rstrip().partition(" ")[2] # remove 'Blender' prefix.
if blender_date is None:
diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh
index 590de594875..26c3701f3e0 100755
--- a/doc/python_api/sphinx_doc_gen.sh
+++ b/doc/python_api/sphinx_doc_gen.sh
@@ -55,7 +55,7 @@ if $DO_EXE_BLENDER ; then
# Don't delete existing docs, now partial updates are used for quick builds.
#
# Disable ASAN error halt since it results in nonzero exit code on any minor issue.
- ASAN_OPTIONS=halt_on_error=0 \
+ ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
$BLENDER_BIN \
--background \
-noaudio \
diff --git a/extern/mantaflow/CMakeLists.txt b/extern/mantaflow/CMakeLists.txt
index 82bf95a9742..c1fa13420b8 100644
--- a/extern/mantaflow/CMakeLists.txt
+++ b/extern/mantaflow/CMakeLists.txt
@@ -75,6 +75,8 @@ endif()
if(WITH_OPENVDB)
add_definitions(-DOPENVDB=1)
+ # OpenVDB headers use deprecated TBB headers, silence warning.
+ add_definitions(-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1)
endif()
if(WITH_OPENVDB_BLOSC)
diff --git a/extern/quadriflow/CMakeLists.txt b/extern/quadriflow/CMakeLists.txt
index e24151d8bf6..1ab2322f73b 100644
--- a/extern/quadriflow/CMakeLists.txt
+++ b/extern/quadriflow/CMakeLists.txt
@@ -102,7 +102,7 @@ set(SRC
)
set(LIB
- ${BOOST_LIBRARIES}
+ ${BOOST_LIBRARIES}
)
blender_add_lib(extern_quadriflow "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/cycles/app/cycles_cubin_cc.cpp b/intern/cycles/app/cycles_cubin_cc.cpp
index 7631cb9bed5..e5d256dd113 100644
--- a/intern/cycles/app/cycles_cubin_cc.cpp
+++ b/intern/cycles/app/cycles_cubin_cc.cpp
@@ -103,7 +103,7 @@ static bool compile_cuda(CompilationSettings &settings)
return false;
}
- /* Tranfer options to a classic C array. */
+ /* Transfer options to a classic C array. */
vector<const char *> opts(options.size());
for (size_t i = 0; i < options.size(); i++) {
opts[i] = options[i].c_str();
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 3ab352e52a2..b1deb5cb64e 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -59,6 +59,7 @@ class CyclesRender(bpy.types.RenderEngine):
bl_use_exclude_layers = True
bl_use_save_buffers = True
bl_use_spherical_stereo = True
+ bl_use_custom_freestyle = True
def __init__(self):
self.session = None
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 964241e9904..4fb5c7f57d1 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -67,11 +67,10 @@ static bool ObtainCacheParticleData(
Transform tfm = get_transform(b_ob->matrix_world());
Transform itfm = transform_quick_inverse(tfm);
- BL::Object::modifiers_iterator b_mod;
- for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
- (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ for (BL::Modifier &b_mod : b_ob->modifiers) {
+ if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
+ (background ? b_mod.show_render() : b_mod.show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
@@ -163,11 +162,10 @@ static bool ObtainCacheParticleUV(Hair *hair,
CData->curve_uv.clear();
- BL::Object::modifiers_iterator b_mod;
- for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
- (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ for (BL::Modifier &b_mod : b_ob->modifiers) {
+ if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
+ (background ? b_mod.show_render() : b_mod.show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
@@ -226,11 +224,10 @@ static bool ObtainCacheParticleVcol(Hair *hair,
CData->curve_vcol.clear();
- BL::Object::modifiers_iterator b_mod;
- for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
- (background ? b_mod->show_render() : b_mod->show_viewport())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ for (BL::Modifier &b_mod : b_ob->modifiers) {
+ if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
+ (background ? b_mod.show_render() : b_mod.show_viewport())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
@@ -510,11 +507,10 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int
bool BlenderSync::object_has_particle_hair(BL::Object b_ob)
{
/* Test if the object has a particle modifier with hair. */
- BL::Object::modifiers_iterator b_mod;
- for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
- if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
- (preview ? b_mod->show_viewport() : b_mod->show_render())) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+ for (BL::Modifier &b_mod : b_ob.modifiers) {
+ if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
+ (preview ? b_mod.show_viewport() : b_mod.show_render())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
@@ -678,9 +674,7 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
/* Export curves and points. */
vector<float> points_length;
- BL::Hair::curves_iterator b_curve_iter;
- for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
- BL::HairCurve b_curve = *b_curve_iter;
+ for (BL::HairCurve &b_curve : b_hair.curves) {
const int first_point_index = b_curve.first_point_index();
const int num_points = b_curve.num_points();
@@ -748,9 +742,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
int num_motion_keys = 0;
int curve_index = 0;
- BL::Hair::curves_iterator b_curve_iter;
- for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
- BL::HairCurve b_curve = *b_curve_iter;
+ for (BL::HairCurve &b_curve : b_hair.curves) {
const int first_point_index = b_curve.first_point_index();
const int num_points = b_curve.num_points();
@@ -855,10 +847,7 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *ha
hair->set_value(socket, new_hair, socket);
}
- hair->attributes.clear();
- foreach (Attribute &attr, new_hair.attributes.attributes) {
- hair->attributes.attributes.push_back(std::move(attr));
- }
+ hair->attributes.update(std::move(new_hair.attributes));
/* tag update */
diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp
index 3ec77719bea..d51b31de638 100644
--- a/intern/cycles/blender/blender_device.cpp
+++ b/intern/cycles/blender/blender_device.cpp
@@ -47,11 +47,9 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
/* Find cycles preferences. */
PointerRNA cpreferences;
- BL::Preferences::addons_iterator b_addon_iter;
- for (b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end();
- ++b_addon_iter) {
- if (b_addon_iter->module() == "cycles") {
- cpreferences = b_addon_iter->preferences().ptr;
+ for (BL::Addon &b_addon : b_preferences.addons) {
+ if (b_addon.module() == "cycles") {
+ cpreferences = b_addon.preferences().ptr;
break;
}
}
diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp
index bd2f0731030..a009018f357 100644
--- a/intern/cycles/blender/blender_geometry.cpp
+++ b/intern/cycles/blender/blender_geometry.cpp
@@ -42,32 +42,20 @@ static Geometry::Type determine_geom_type(BL::Object &b_ob, bool use_particle_ha
return Geometry::MESH;
}
-Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
- BL::Object &b_ob,
- BL::Object &b_ob_instance,
- bool object_updated,
- bool use_particle_hair,
- TaskPool *task_pool)
+array<Node *> BlenderSync::find_used_shaders(BL::Object &b_ob)
{
- /* Test if we can instance or if the object is modified. */
- BL::ID b_ob_data = b_ob.data();
- BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
BL::Material material_override = view_layer.material_override;
Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume :
scene->default_surface;
- Geometry::Type geom_type = determine_geom_type(b_ob, use_particle_hair);
- GeometryKey key(b_key_id.ptr.data, geom_type);
- /* Find shader indices. */
array<Node *> used_shaders;
- BL::Object::material_slots_iterator slot;
- for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
+ for (BL::MaterialSlot &b_slot : b_ob.material_slots) {
if (material_override) {
find_shader(material_override, used_shaders, default_shader);
}
else {
- BL::ID b_material(slot->material());
+ BL::ID b_material(b_slot.material());
find_shader(b_material, used_shaders, default_shader);
}
}
@@ -79,6 +67,25 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
used_shaders.push_back_slow(default_shader);
}
+ return used_shaders;
+}
+
+Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
+ BL::Object &b_ob,
+ BL::Object &b_ob_instance,
+ bool object_updated,
+ bool use_particle_hair,
+ TaskPool *task_pool)
+{
+ /* Test if we can instance or if the object is modified. */
+ BL::ID b_ob_data = b_ob.data();
+ BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
+ Geometry::Type geom_type = determine_geom_type(b_ob, use_particle_hair);
+ GeometryKey key(b_key_id.ptr.data, geom_type);
+
+ /* Find shader indices. */
+ array<Node *> used_shaders = find_used_shaders(b_ob);
+
/* Ensure we only sync instanced geometry once. */
Geometry *geom = geometry_map.find(key);
if (geom) {
@@ -124,7 +131,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
foreach (Node *node, geom->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
- if (shader->need_update_geometry) {
+ if (shader->need_update_geometry()) {
attribute_recalc = true;
}
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 3420025f472..7edf797e096 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -285,12 +285,10 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
BL::Mesh &b_mesh,
bool subdivision)
{
- BL::Mesh::sculpt_vertex_colors_iterator l;
-
- for (b_mesh.sculpt_vertex_colors.begin(l); l != b_mesh.sculpt_vertex_colors.end(); ++l) {
- const bool active_render = l->active_render();
+ for (BL::MeshVertColorLayer &l : b_mesh.sculpt_vertex_colors) {
+ const bool active_render = l.active_render();
AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
- ustring vcol_name = ustring(l->name().c_str());
+ ustring vcol_name = ustring(l.name().c_str());
const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
mesh->need_attribute(scene, vcol_std);
@@ -307,7 +305,7 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
int numverts = b_mesh.vertices.length();
for (int i = 0; i < numverts; i++) {
- *(cdata++) = get_float4(l->data[i].color());
+ *(cdata++) = get_float4(l.data[i].color());
}
}
}
@@ -315,12 +313,10 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
/* Create vertex color attributes. */
static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
{
- BL::Mesh::vertex_colors_iterator l;
-
- for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
- const bool active_render = l->active_render();
+ for (BL::MeshLoopColorLayer &l : b_mesh.vertex_colors) {
+ const bool active_render = l.active_render();
AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
- ustring vcol_name = ustring(l->name().c_str());
+ ustring vcol_name = ustring(l.name().c_str());
const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
mesh->need_attribute(scene, vcol_std);
@@ -339,13 +335,12 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
vcol_attr = mesh->subd_attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
}
- BL::Mesh::polygons_iterator p;
uchar4 *cdata = vcol_attr->data_uchar4();
- for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- int n = p->loop_total();
+ for (BL::MeshPolygon &p : b_mesh.polygons) {
+ int n = p.loop_total();
for (int i = 0; i < n; i++) {
- float4 color = get_float4(l->data[p->loop_start() + i].color());
+ float4 color = get_float4(l.data[p.loop_start() + i].color());
/* Compress/encode vertex color using the sRGB curve. */
*(cdata++) = color_float4_to_uchar4(color);
}
@@ -359,14 +354,13 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
vcol_attr = mesh->attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
}
- BL::Mesh::loop_triangles_iterator t;
uchar4 *cdata = vcol_attr->data_uchar4();
- for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- int3 li = get_int3(t->loops());
- float4 c1 = get_float4(l->data[li[0]].color());
- float4 c2 = get_float4(l->data[li[1]].color());
- float4 c3 = get_float4(l->data[li[2]].color());
+ for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
+ int3 li = get_int3(t.loops());
+ float4 c1 = get_float4(l.data[li[0]].color());
+ float4 c2 = get_float4(l.data[li[1]].color());
+ float4 c3 = get_float4(l.data[li[2]].color());
/* Compress/encode vertex color using the sRGB curve. */
cdata[0] = color_float4_to_uchar4(c1);
@@ -383,14 +377,12 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
{
if (b_mesh.uv_layers.length() != 0) {
- BL::Mesh::uv_layers_iterator l;
-
- for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
- const bool active_render = l->active_render();
+ for (BL::MeshUVLoopLayer &l : b_mesh.uv_layers) {
+ const bool active_render = l.active_render();
AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
- ustring uv_name = ustring(l->name().c_str());
+ ustring uv_name = ustring(l.name().c_str());
AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
- ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
+ ustring tangent_name = ustring((string(l.name().c_str()) + ".tangent").c_str());
/* Denotes whether UV map was requested directly. */
const bool need_uv = mesh->need_attribute(scene, uv_name) ||
@@ -412,14 +404,13 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
}
- BL::Mesh::loop_triangles_iterator t;
float2 *fdata = uv_attr->data_float2();
- for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- int3 li = get_int3(t->loops());
- fdata[0] = get_float2(l->data[li[0]].uv());
- fdata[1] = get_float2(l->data[li[1]].uv());
- fdata[2] = get_float2(l->data[li[2]].uv());
+ for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
+ int3 li = get_int3(t.loops());
+ fdata[0] = get_float2(l.data[li[0]].uv());
+ fdata[1] = get_float2(l.data[li[1]].uv());
+ fdata[2] = get_float2(l.data[li[2]].uv());
fdata += 3;
}
}
@@ -427,10 +418,10 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
/* UV tangent */
if (need_tangent) {
AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
- ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
+ ustring sign_name = ustring((string(l.name().c_str()) + ".tangent_sign").c_str());
bool need_sign = (mesh->need_attribute(scene, sign_name) ||
mesh->need_attribute(scene, sign_std));
- mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
+ mikk_compute_tangents(b_mesh, l.name().c_str(), mesh, need_sign, active_render);
}
/* Remove temporarily created UV attribute. */
if (!need_uv && uv_attr != NULL) {
@@ -480,13 +471,12 @@ static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
uv_attr->flags |= ATTR_SUBDIVIDED;
}
- BL::Mesh::polygons_iterator p;
float2 *fdata = uv_attr->data_float2();
- for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- int n = p->loop_total();
+ for (BL::MeshPolygon &p : b_mesh.polygons) {
+ int n = p.loop_total();
for (int j = 0; j < n; j++) {
- *(fdata++) = get_float2(l->data[p->loop_start() + j].uv());
+ *(fdata++) = get_float2(l->data[p.loop_start() + j].uv());
}
}
}
@@ -706,9 +696,8 @@ static void attr_create_random_per_island(Scene *scene,
DisjointSet vertices_sets(number_of_vertices);
- BL::Mesh::edges_iterator e;
- for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
- vertices_sets.join(e->vertices()[0], e->vertices()[1]);
+ for (BL::MeshEdge &e : b_mesh.edges) {
+ vertices_sets.join(e.vertices()[0], e.vertices()[1]);
}
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
@@ -716,15 +705,13 @@ static void attr_create_random_per_island(Scene *scene,
float *data = attribute->data_float();
if (!subdivision) {
- BL::Mesh::loop_triangles_iterator t;
- for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- data[t->index()] = hash_uint_to_float(vertices_sets.find(t->vertices()[0]));
+ for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
+ data[t.index()] = hash_uint_to_float(vertices_sets.find(t.vertices()[0]));
}
}
else {
- BL::Mesh::polygons_iterator p;
- for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- data[p->index()] = hash_uint_to_float(vertices_sets.find(p->vertices()[0]));
+ for (BL::MeshPolygon &p : b_mesh.polygons) {
+ data[p.index()] = hash_uint_to_float(vertices_sets.find(p.vertices()[0]));
}
}
}
@@ -756,10 +743,9 @@ static void create_mesh(Scene *scene,
numtris = numfaces;
}
else {
- BL::Mesh::polygons_iterator p;
- for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- numngons += (p->loop_total() == 4) ? 0 : 1;
- numcorners += p->loop_total();
+ for (BL::MeshPolygon &p : b_mesh.polygons) {
+ numngons += (p.loop_total() == 4) ? 0 : 1;
+ numcorners += p.loop_total();
}
}
@@ -803,17 +789,15 @@ static void create_mesh(Scene *scene,
/* create faces */
if (!subdivision) {
- BL::Mesh::loop_triangles_iterator t;
-
- for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
- BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
- int3 vi = get_int3(t->vertices());
+ for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
+ BL::MeshPolygon p = b_mesh.polygons[t.polygon_index()];
+ int3 vi = get_int3(t.vertices());
int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
bool smooth = p.use_smooth() || use_loop_normals;
if (use_loop_normals) {
- BL::Array<float, 9> loop_normals = t->split_normals();
+ BL::Array<float, 9> loop_normals = t.split_normals();
for (int i = 0; i < 3; i++) {
N[vi[i]] = make_float3(
loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
@@ -828,18 +812,17 @@ static void create_mesh(Scene *scene,
}
}
else {
- BL::Mesh::polygons_iterator p;
vector<int> vi;
- for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
- int n = p->loop_total();
- int shader = clamp(p->material_index(), 0, used_shaders.size() - 1);
- bool smooth = p->use_smooth() || use_loop_normals;
+ for (BL::MeshPolygon &p : b_mesh.polygons) {
+ int n = p.loop_total();
+ int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
+ bool smooth = p.use_smooth() || use_loop_normals;
vi.resize(n);
for (int i = 0; i < n; i++) {
/* NOTE: Autosmooth is already taken care about. */
- vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
+ vi[i] = b_mesh.loops[p.loop_start() + i].vertex_index();
}
/* create subd faces */
@@ -891,19 +874,18 @@ static void create_subd_mesh(Scene *scene,
/* export creases */
size_t num_creases = 0;
- BL::Mesh::edges_iterator e;
- for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
- if (e->crease() != 0.0f) {
+ for (BL::MeshEdge &e : b_mesh.edges) {
+ if (e.crease() != 0.0f) {
num_creases++;
}
}
mesh->reserve_subd_creases(num_creases);
- for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
- if (e->crease() != 0.0f) {
- mesh->add_crease(e->vertices()[0], e->vertices()[1], e->crease());
+ for (BL::MeshEdge &e : b_mesh.edges) {
+ if (e.crease() != 0.0f) {
+ mesh->add_crease(e.vertices()[0], e.vertices()[1], e.crease());
}
}
@@ -1075,15 +1057,8 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me
mesh->set_value(socket, new_mesh, socket);
}
- mesh->attributes.clear();
- foreach (Attribute &attr, new_mesh.attributes.attributes) {
- mesh->attributes.attributes.push_back(std::move(attr));
- }
-
- mesh->subd_attributes.clear();
- foreach (Attribute &attr, new_mesh.subd_attributes.attributes) {
- mesh->subd_attributes.attributes.push_back(std::move(attr));
- }
+ mesh->attributes.update(std::move(new_mesh.attributes));
+ mesh->subd_attributes.update(std::move(new_mesh.subd_attributes));
mesh->set_num_subd_faces(new_mesh.get_num_subd_faces());
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 5261fbcee07..f0460b129c2 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -51,10 +51,11 @@ bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
}
else {
/* object level material links */
- BL::Object::material_slots_iterator slot;
- for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
- if (slot->link() == BL::MaterialSlot::link_OBJECT)
+ for (BL::MaterialSlot &b_slot : b_ob.material_slots) {
+ if (b_slot.link() == BL::MaterialSlot::link_OBJECT) {
return true;
+ }
+ }
}
return false;
@@ -243,9 +244,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
/* holdout */
object->set_use_holdout(use_holdout);
- if (object->use_holdout_is_modified()) {
- scene->object_manager->tag_update(scene);
- }
object->set_visibility(visibility);
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index ca221b229b4..ae43dae4dc1 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -31,7 +31,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
BL::DepsgraphObjectInstance &b_instance,
Object *object)
{
- /* test if this dupli was generated from a particle sytem */
+ /* Test if this dupli was generated from a particle system. */
BL::ParticleSystem b_psys = b_instance.particle_system();
if (!b_psys)
return false;
@@ -57,7 +57,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
/* no update needed? */
if (!need_update && !object->get_geometry()->is_modified() &&
- !scene->object_manager->need_update)
+ !scene->object_manager->need_update())
return true;
/* first time used in this sync loop? clear and tag update */
@@ -85,7 +85,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
object->set_particle_index(psys->particles.size() - 1);
if (object->particle_index_is_modified())
- scene->object_manager->tag_update(scene);
+ scene->object_manager->tag_update(scene, ObjectManager::PARTICLE_MODIFIED);
/* return that this object has particle data */
return true;
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 525525e1047..5646bd5b2eb 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -597,22 +597,19 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
bool removed;
do {
- BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
-
removed = false;
- for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
- if (used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
- b_node.inputs.remove(b_data, *b_input);
+ for (BL::NodeSocket &b_input : b_node.inputs) {
+ if (used_sockets.find(b_input.ptr.data) == used_sockets.end()) {
+ b_node.inputs.remove(b_data, b_input);
removed = true;
break;
}
}
- for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
- if (used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
- b_node.outputs.remove(b_data, *b_output);
+ for (BL::NodeSocket &b_output : b_node.outputs) {
+ if (used_sockets.find(b_output.ptr.data) == used_sockets.end()) {
+ b_node.outputs.remove(b_data, b_output);
removed = true;
break;
}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 8566d0e7ed5..ae13310789e 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -358,11 +358,7 @@ void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
if (do_read_only) {
/* copy each pass */
- BL::RenderLayer::passes_iterator b_iter;
-
- for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
- BL::RenderPass b_pass(*b_iter);
-
+ for (BL::RenderPass &b_pass : b_rlay.passes) {
/* find matching pass type */
PassType pass_type = BlenderSync::get_pass_type(b_pass);
int components = b_pass.channels();
@@ -552,7 +548,6 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
int seed = scene->integrator->get_seed();
seed += hash_uint2(seed, hash_uint2(view_index * 0xdeadbeef, 0));
scene->integrator->set_seed(seed);
- scene->integrator->tag_update(scene);
}
/* Update number of samples per layer. */
@@ -736,10 +731,7 @@ void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay,
if (!do_update_only) {
/* copy each pass */
- BL::RenderLayer::passes_iterator b_iter;
-
- for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
- BL::RenderPass b_pass(*b_iter);
+ for (BL::RenderPass &b_pass : b_rlay.passes) {
int components = b_pass.channels();
/* Copy pixels from regular render passes. */
@@ -1116,10 +1108,6 @@ void BlenderSession::update_resumable_tile_manager(int num_samples)
scene->integrator->set_start_sample(rounded_range_start_sample);
- if (scene->integrator->is_modified()) {
- scene->integrator->tag_update(scene);
- }
-
session->tile_manager.range_start_sample = rounded_range_start_sample;
session->tile_manager.range_num_samples = rounded_range_num_samples;
}
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 68db8a2fb58..d967b81c854 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -136,7 +136,7 @@ class BlenderSession {
/* ** Resumable render ** */
- /* Overall number of chunks in which the sample range is to be devided. */
+ /* Overall number of chunks in which the sample range is to be divided. */
static int num_resumable_chunks;
/* Current resumable chunk index to render. */
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index ac86cf3345c..02a6638b083 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -148,15 +148,13 @@ BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_r
static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
{
- BL::Node::outputs_iterator b_out;
-
- for (b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
- if (b_out->name() == name)
- return *b_out;
-
+ for (BL::NodeSocket &b_out : b_node.outputs) {
+ if (b_out.name() == name) {
+ return b_out;
+ }
+ }
assert(0);
-
- return *b_out;
+ return *b_node.outputs.begin();
}
static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
@@ -723,9 +721,8 @@ static ShaderNode *add_node(Scene *scene,
image->set_alpha_type(get_image_alpha_type(b_image));
array<int> tiles;
- BL::Image::tiles_iterator b_iter;
- for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) {
- tiles.push_back_slow(b_iter->number());
+ for (BL::UDIMTile &b_tile : b_image.tiles) {
+ tiles.push_back_slow(b_tile.number());
}
image->set_tiles(tiles);
@@ -885,7 +882,7 @@ static ShaderNode *add_node(Scene *scene,
sky->set_sun_intensity(b_sky_node.sun_intensity());
sky->set_sun_elevation(b_sky_node.sun_elevation());
sky->set_sun_rotation(b_sky_node.sun_rotation());
- sky->set_altitude(1000.0f * b_sky_node.altitude());
+ sky->set_altitude(b_sky_node.altitude());
sky->set_air_density(b_sky_node.air_density());
sky->set_dust_density(b_sky_node.dust_density());
sky->set_ozone_density(b_sky_node.ozone_density());
@@ -1012,18 +1009,18 @@ static ShaderInput *node_find_input_by_name(ShaderNode *node,
string name = b_socket.name();
if (node_use_modified_socket_name(node)) {
- BL::Node::inputs_iterator b_input;
bool found = false;
int counter = 0, total = 0;
- for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
- if (b_input->name() == name) {
- if (!found)
+ for (BL::NodeSocket &b_input : b_node.inputs) {
+ if (b_input.name() == name) {
+ if (!found) {
counter++;
+ }
total++;
}
- if (b_input->ptr.data == b_socket.ptr.data)
+ if (b_input.ptr.data == b_socket.ptr.data)
found = true;
}
@@ -1045,19 +1042,20 @@ static ShaderOutput *node_find_output_by_name(ShaderNode *node,
string name = b_socket.name();
if (node_use_modified_socket_name(node)) {
- BL::Node::outputs_iterator b_output;
bool found = false;
int counter = 0, total = 0;
- for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
- if (b_output->name() == name) {
- if (!found)
+ for (BL::NodeSocket &b_output : b_node.outputs) {
+ if (b_output.name() == name) {
+ if (!found) {
counter++;
+ }
total++;
}
- if (b_output->ptr.data == b_socket.ptr.data)
+ if (b_output.ptr.data == b_socket.ptr.data) {
found = true;
+ }
}
/* rename if needed */
@@ -1082,25 +1080,19 @@ static void add_nodes(Scene *scene,
const ProxyMap &proxy_output_map)
{
/* add nodes */
- BL::ShaderNodeTree::nodes_iterator b_node;
PtrInputMap input_map;
PtrOutputMap output_map;
- BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
-
/* find the node to use for output if there are multiple */
BL::ShaderNode output_node = b_ntree.get_output_node(
BL::ShaderNodeOutputMaterial::target_CYCLES);
/* add nodes */
- for (b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
- if (b_node->mute() || b_node->is_a(&RNA_NodeReroute)) {
+ for (BL::Node &b_node : b_ntree.nodes) {
+ if (b_node.mute() || b_node.is_a(&RNA_NodeReroute)) {
/* replace muted node with internal links */
- BL::Node::internal_links_iterator b_link;
- for (b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end();
- ++b_link) {
- BL::NodeSocket to_socket(b_link->to_socket());
+ for (BL::NodeLink &b_link : b_node.internal_links) {
+ BL::NodeSocket to_socket(b_link.to_socket());
SocketType::Type to_socket_type = convert_socket_type(to_socket);
if (to_socket_type == SocketType::UNDEFINED) {
continue;
@@ -1108,22 +1100,22 @@ static void add_nodes(Scene *scene,
ConvertNode *proxy = graph->create_node<ConvertNode>(to_socket_type, to_socket_type, true);
- input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
- output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
+ input_map[b_link.from_socket().ptr.data] = proxy->inputs[0];
+ output_map[b_link.to_socket().ptr.data] = proxy->outputs[0];
graph->add(proxy);
}
}
- else if (b_node->is_a(&RNA_ShaderNodeGroup) || b_node->is_a(&RNA_NodeCustomGroup) ||
- b_node->is_a(&RNA_ShaderNodeCustomGroup)) {
+ else if (b_node.is_a(&RNA_ShaderNodeGroup) || b_node.is_a(&RNA_NodeCustomGroup) ||
+ b_node.is_a(&RNA_ShaderNodeCustomGroup)) {
BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
- if (b_node->is_a(&RNA_ShaderNodeGroup))
- b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(*b_node)).node_tree());
- else if (b_node->is_a(&RNA_NodeCustomGroup))
- b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
+ if (b_node.is_a(&RNA_ShaderNodeGroup))
+ b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(b_node)).node_tree());
+ else if (b_node.is_a(&RNA_NodeCustomGroup))
+ b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(b_node)).node_tree());
else
- b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(*b_node)).node_tree());
+ b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(b_node)).node_tree());
ProxyMap group_proxy_input_map, group_proxy_output_map;
@@ -1131,8 +1123,8 @@ static void add_nodes(Scene *scene,
* Do this even if the node group has no internal tree,
* so that links have something to connect to and assert won't fail.
*/
- for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- SocketType::Type input_type = convert_socket_type(*b_input);
+ for (BL::NodeSocket &b_input : b_node.inputs) {
+ SocketType::Type input_type = convert_socket_type(b_input);
if (input_type == SocketType::UNDEFINED) {
continue;
}
@@ -1141,14 +1133,14 @@ static void add_nodes(Scene *scene,
graph->add(proxy);
/* register the proxy node for internal binding */
- group_proxy_input_map[b_input->identifier()] = proxy;
+ group_proxy_input_map[b_input.identifier()] = proxy;
- input_map[b_input->ptr.data] = proxy->inputs[0];
+ input_map[b_input.ptr.data] = proxy->inputs[0];
- set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
+ set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
}
- for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- SocketType::Type output_type = convert_socket_type(*b_output);
+ for (BL::NodeSocket &b_output : b_node.outputs) {
+ SocketType::Type output_type = convert_socket_type(b_output);
if (output_type == SocketType::UNDEFINED) {
continue;
}
@@ -1157,9 +1149,9 @@ static void add_nodes(Scene *scene,
graph->add(proxy);
/* register the proxy node for internal binding */
- group_proxy_output_map[b_output->identifier()] = proxy;
+ group_proxy_output_map[b_output.identifier()] = proxy;
- output_map[b_output->ptr.data] = proxy->outputs[0];
+ output_map[b_output.ptr.data] = proxy->outputs[0];
}
if (b_group_ntree) {
@@ -1174,30 +1166,30 @@ static void add_nodes(Scene *scene,
group_proxy_output_map);
}
}
- else if (b_node->is_a(&RNA_NodeGroupInput)) {
+ else if (b_node.is_a(&RNA_NodeGroupInput)) {
/* map each socket to a proxy node */
- for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output->identifier());
+ for (BL::NodeSocket &b_output : b_node.outputs) {
+ ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output.identifier());
if (proxy_it != proxy_input_map.end()) {
ConvertNode *proxy = proxy_it->second;
- output_map[b_output->ptr.data] = proxy->outputs[0];
+ output_map[b_output.ptr.data] = proxy->outputs[0];
}
}
}
- else if (b_node->is_a(&RNA_NodeGroupOutput)) {
- BL::NodeGroupOutput b_output_node(*b_node);
+ else if (b_node.is_a(&RNA_NodeGroupOutput)) {
+ BL::NodeGroupOutput b_output_node(b_node);
/* only the active group output is used */
if (b_output_node.is_active_output()) {
/* map each socket to a proxy node */
- for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input->identifier());
+ for (BL::NodeSocket &b_input : b_node.inputs) {
+ ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input.identifier());
if (proxy_it != proxy_output_map.end()) {
ConvertNode *proxy = proxy_it->second;
- input_map[b_input->ptr.data] = proxy->inputs[0];
+ input_map[b_input.ptr.data] = proxy->inputs[0];
- set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
+ set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
}
}
}
@@ -1205,52 +1197,49 @@ static void add_nodes(Scene *scene,
else {
ShaderNode *node = NULL;
- if (b_node->ptr.data == output_node.ptr.data) {
+ if (b_node.ptr.data == output_node.ptr.data) {
node = graph->output();
}
else {
- BL::ShaderNode b_shader_node(*b_node);
+ BL::ShaderNode b_shader_node(b_node);
node = add_node(
scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree, b_shader_node);
}
if (node) {
/* map node sockets for linking */
- for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- ShaderInput *input = node_find_input_by_name(node, *b_node, *b_input);
+ for (BL::NodeSocket &b_input : b_node.inputs) {
+ ShaderInput *input = node_find_input_by_name(node, b_node, b_input);
if (!input) {
/* XXX should not happen, report error? */
continue;
}
- input_map[b_input->ptr.data] = input;
+ input_map[b_input.ptr.data] = input;
- set_default_value(input, *b_input, b_data, b_ntree);
+ set_default_value(input, b_input, b_data, b_ntree);
}
- for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- ShaderOutput *output = node_find_output_by_name(node, *b_node, *b_output);
+ for (BL::NodeSocket &b_output : b_node.outputs) {
+ ShaderOutput *output = node_find_output_by_name(node, b_node, b_output);
if (!output) {
/* XXX should not happen, report error? */
continue;
}
- output_map[b_output->ptr.data] = output;
+ output_map[b_output.ptr.data] = output;
}
}
}
}
/* connect nodes */
- BL::NodeTree::links_iterator b_link;
-
- for (b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
+ for (BL::NodeLink &b_link : b_ntree.links) {
/* Ignore invalid links to avoid unwanted cycles created in graph.
* Also ignore links with unavailable sockets. */
- if (!(b_link->is_valid() && b_link->from_socket().enabled() &&
- b_link->to_socket().enabled())) {
+ if (!(b_link.is_valid() && b_link.from_socket().enabled() && b_link.to_socket().enabled())) {
continue;
}
/* get blender link data */
- BL::NodeSocket b_from_sock = b_link->from_socket();
- BL::NodeSocket b_to_sock = b_link->to_socket();
+ BL::NodeSocket b_from_sock = b_link.from_socket();
+ BL::NodeSocket b_to_sock = b_link.to_socket();
ShaderOutput *output = 0;
ShaderInput *input = 0;
@@ -1298,13 +1287,12 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
TaskPool pool;
set<Shader *> updated_shaders;
- BL::Depsgraph::ids_iterator b_id;
- for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
- if (!b_id->is_a(&RNA_Material)) {
+ for (BL::ID &b_id : b_depsgraph.ids) {
+ if (!b_id.is_a(&RNA_Material)) {
continue;
}
- BL::Material b_mat(*b_id);
+ BL::Material b_mat(b_id);
Shader *shader;
/* test if we need to sync */
@@ -1497,7 +1485,6 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
shader->set_graph(graph);
shader->tag_update(scene);
- background->tag_update(scene);
}
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -1517,8 +1504,7 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
viewport_parameters.custom_viewport_parameters());
background->set_use_ao(background->get_use_ao() && view_layer.use_background_ao);
- if (background->is_modified())
- background->tag_update(scene);
+ background->tag_update(scene);
}
/* Sync Lights */
@@ -1527,13 +1513,12 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
{
shader_map.set_default(scene->default_light);
- BL::Depsgraph::ids_iterator b_id;
- for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
- if (!b_id->is_a(&RNA_Light)) {
+ for (BL::ID &b_id : b_depsgraph.ids) {
+ if (!b_id.is_a(&RNA_Light)) {
continue;
}
- BL::Light b_light(*b_id);
+ BL::Light b_light(b_id);
Shader *shader;
/* test if we need to sync */
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index e27daa2488d..aea601480bf 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -24,6 +24,7 @@
#include "render/mesh.h"
#include "render/nodes.h"
#include "render/object.h"
+#include "render/procedural.h"
#include "render/scene.h"
#include "render/shader.h"
@@ -131,9 +132,8 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
/* Iterate over all IDs in this depsgraph. */
- BL::Depsgraph::updates_iterator b_update;
- for (b_depsgraph.updates.begin(b_update); b_update != b_depsgraph.updates.end(); ++b_update) {
- BL::ID b_id(b_update->id());
+ for (BL::DepsgraphUpdate &b_update : b_depsgraph.updates) {
+ BL::ID b_id(b_update.id());
/* Material */
if (b_id.is_a(&RNA_Material)) {
@@ -151,17 +151,17 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
const bool is_geometry = object_is_geometry(b_ob);
const bool is_light = !is_geometry && object_is_light(b_ob);
- if (b_ob.is_instancer() && b_update->is_updated_shading()) {
+ if (b_ob.is_instancer() && b_update.is_updated_shading()) {
/* Needed for e.g. object color updates on instancer. */
object_map.set_recalc(b_ob);
}
if (is_geometry || is_light) {
- const bool updated_geometry = b_update->is_updated_geometry();
+ const bool updated_geometry = b_update.is_updated_geometry();
/* Geometry (mesh, hair, volume). */
if (is_geometry) {
- if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
+ if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
object_map.set_recalc(b_ob);
}
@@ -181,7 +181,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
/* Light */
else if (is_light) {
- if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
+ if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
object_map.set_recalc(b_ob);
light_map.set_recalc(b_ob);
}
@@ -302,11 +302,6 @@ void BlenderSync::sync_integrator()
integrator->set_sample_clamp_direct(get_float(cscene, "sample_clamp_direct"));
integrator->set_sample_clamp_indirect(get_float(cscene, "sample_clamp_indirect"));
if (!preview) {
- if (integrator->get_motion_blur() != r.use_motion_blur()) {
- scene->object_manager->tag_update(scene);
- scene->camera->tag_modified();
- }
-
integrator->set_motion_blur(r.use_motion_blur());
}
@@ -375,8 +370,8 @@ void BlenderSync::sync_integrator()
integrator->set_ao_bounces(0);
}
- if (integrator->is_modified())
- integrator->tag_update(scene);
+ /* UPDATE_NONE as we don't want to tag the integrator as modified, just tag dependent things */
+ integrator->tag_update(scene, Integrator::UPDATE_NONE);
}
/* Film */
@@ -471,16 +466,15 @@ void BlenderSync::sync_images()
return;
}
/* Free buffers used by images which are not needed for render. */
- BL::BlendData::images_iterator b_image;
- for (b_data.images.begin(b_image); b_image != b_data.images.end(); ++b_image) {
+ for (BL::Image &b_image : b_data.images) {
/* TODO(sergey): Consider making it an utility function to check
* whether image is considered builtin.
*/
- const bool is_builtin = b_image->packed_file() ||
- b_image->source() == BL::Image::source_GENERATED ||
- b_image->source() == BL::Image::source_MOVIE || b_engine.is_preview();
+ const bool is_builtin = b_image.packed_file() ||
+ b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE || b_engine.is_preview();
if (is_builtin == false) {
- b_image->buffers_free();
+ b_image.buffers_free();
}
/* TODO(sergey): Free builtin images not used by any shader. */
}
@@ -581,10 +575,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
vector<Pass> passes;
/* loop over passes */
- BL::RenderLayer::passes_iterator b_pass_iter;
-
- for (b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
- BL::RenderPass b_pass(*b_pass_iter);
+ for (BL::RenderPass &b_pass : b_rlay.passes) {
PassType pass_type = get_pass_type(b_pass);
if (pass_type == PASS_MOTION && scene->integrator->get_motion_blur())
@@ -729,7 +720,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
scene->film->tag_passes_update(scene, passes);
- scene->integrator->tag_update(scene);
+ scene->integrator->tag_update(scene, Integrator::UPDATE_ALL);
return passes;
}
@@ -752,9 +743,8 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
/* TODO(sergey): We can actually remove the whole dependency graph,
* but that will need some API support first.
*/
- BL::Depsgraph::objects_iterator b_ob;
- for (b_depsgraph.objects.begin(b_ob); b_ob != b_depsgraph.objects.end(); ++b_ob) {
- b_ob->cache_release();
+ for (BL::Object &b_ob : b_depsgraph.objects) {
+ b_ob.cache_release();
}
}
@@ -952,7 +942,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
else if (shadingsystem == 1)
params.shadingsystem = SHADINGSYSTEM_OSL;
- /* color managagement */
+ /* Color management. */
params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
if (b_engine.is_preview()) {
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index ccf059d7704..1c43522a57e 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -134,6 +134,7 @@ class BlenderSync {
void sync_view();
/* Shader */
+ array<Node *> find_used_shaders(BL::Object &b_ob);
void sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all);
void sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d);
void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 5185ebae789..43dbb4105df 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -538,11 +538,9 @@ static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_
static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object &b_ob)
{
- BL::Object::modifiers_iterator b_mod;
-
- for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
- if (b_mod->is_a(&RNA_FluidModifier)) {
- BL::FluidModifier b_mmd(*b_mod);
+ for (BL::Modifier &b_mod : b_ob.modifiers) {
+ if (b_mod.is_a(&RNA_FluidModifier)) {
+ BL::FluidModifier b_mmd(b_mod);
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_LIQUID) {
@@ -556,11 +554,9 @@ static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object
static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b_ob)
{
- BL::Object::modifiers_iterator b_mod;
-
- for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
- if (b_mod->is_a(&RNA_FluidModifier)) {
- BL::FluidModifier b_mmd(*b_mod);
+ for (BL::Modifier &b_mod : b_ob.modifiers) {
+ if (b_mod.is_a(&RNA_FluidModifier)) {
+ BL::FluidModifier b_mmd(b_mod);
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_GAS) {
diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index 094d4bbc08c..410f7a72cf5 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -222,9 +222,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
b_volume.grids.load(b_data.ptr.data);
#ifdef WITH_OPENVDB
- BL::Volume::grids_iterator b_grid_iter;
- for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
- BL::VolumeGrid b_volume_grid(*b_grid_iter);
+ for (BL::VolumeGrid &b_volume_grid : b_volume.grids) {
if (b_volume_grid.name() == grid_name) {
const bool unload = !b_volume_grid.is_loaded();
@@ -260,9 +258,7 @@ static void sync_volume_object(BL::BlendData &b_data,
volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT));
/* Find grid with matching name. */
- BL::Volume::grids_iterator b_grid_iter;
- for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
- BL::VolumeGrid b_grid = *b_grid_iter;
+ for (BL::VolumeGrid &b_grid : b_volume.grids) {
ustring name = ustring(b_grid.name());
AttributeStandard std = ATTR_STD_NONE;
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 1727082b7ec..296f9130f43 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -703,7 +703,7 @@ BVHNode *BVHBuild::build_node(const BVHRange &range,
unalignedSplitSAH = params.sah_node_cost * unaligned_split.bounds.half_area() +
params.sah_primitive_cost * unaligned_split.nodeSAH;
/* TOOD(sergey): Check we can create leaf already. */
- /* Check whether unaligned split is better than the regulat one. */
+ /* Check whether unaligned split is better than the regular one. */
if (unalignedSplitSAH < splitSAH) {
do_unalinged_split = true;
}
@@ -842,7 +842,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
vector<BVHReference, LeafReferenceStackAllocator> object_references;
uint visibility[PRIMITIVE_NUM_TOTAL] = {0};
- /* NOTE: Keep initializtion in sync with actual number of primitives. */
+ /* NOTE: Keep initialization in sync with actual number of primitives. */
BoundBox bounds[PRIMITIVE_NUM_TOTAL] = {
BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty};
int ob_num = 0;
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index b29f392a754..04ff598621a 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -383,7 +383,7 @@ if(WITH_CYCLES_OPENSUBDIV)
optimized ${OPENSUBDIV_ROOT_DIR}/lib/osdGPU.lib
debug ${OPENSUBDIV_ROOT_DIR}/lib/osdCPU_d.lib
debug ${OPENSUBDIV_ROOT_DIR}/lib/osdGPU_d.lib
- )
+ )
endif()
endif()
endif()
diff --git a/intern/cycles/device/cuda/device_cuda_impl.cpp b/intern/cycles/device/cuda/device_cuda_impl.cpp
index cff30eb9b48..44a51835f4c 100644
--- a/intern/cycles/device/cuda/device_cuda_impl.cpp
+++ b/intern/cycles/device/cuda/device_cuda_impl.cpp
@@ -184,7 +184,7 @@ CUDADevice::CUDADevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool
functions.loaded = false;
- /* Intialize CUDA. */
+ /* Initialize CUDA. */
CUresult result = cuInit(0);
if (result != CUDA_SUCCESS) {
set_error(string_printf("Failed to initialize CUDA runtime (%s)", cuewErrorString(result)));
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 00b2aa864aa..1f63a152458 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -259,6 +259,8 @@ class device_memory {
device_ptr original_device_ptr;
size_t original_device_size;
Device *original_device;
+ bool need_realloc_;
+ bool modified;
};
/* Device Only Memory
@@ -329,6 +331,8 @@ template<typename T> class device_vector : public device_memory {
{
data_type = device_type_traits<T>::data_type;
data_elements = device_type_traits<T>::num_elements;
+ modified = true;
+ need_realloc_ = true;
assert(data_elements > 0);
}
@@ -347,6 +351,7 @@ template<typename T> class device_vector : public device_memory {
device_free();
host_free();
host_pointer = host_alloc(sizeof(T) * new_size);
+ modified = true;
assert(device_pointer == 0);
}
@@ -400,6 +405,19 @@ template<typename T> class device_vector : public device_memory {
assert(device_pointer == 0);
}
+ void give_data(array<T> &to)
+ {
+ device_free();
+
+ to.set_data((T *)host_pointer, data_size);
+ data_size = 0;
+ data_width = 0;
+ data_height = 0;
+ data_depth = 0;
+ host_pointer = 0;
+ assert(device_pointer == 0);
+ }
+
/* Free device and host memory. */
void free()
{
@@ -411,10 +429,40 @@ template<typename T> class device_vector : public device_memory {
data_height = 0;
data_depth = 0;
host_pointer = 0;
+ modified = true;
+ need_realloc_ = true;
assert(device_pointer == 0);
}
- size_t size()
+ void free_if_need_realloc(bool force_free)
+ {
+ if (need_realloc_ || force_free) {
+ free();
+ }
+ }
+
+ bool is_modified() const
+ {
+ return modified;
+ }
+
+ bool need_realloc()
+ {
+ return need_realloc_;
+ }
+
+ void tag_modified()
+ {
+ modified = true;
+ }
+
+ void tag_realloc()
+ {
+ need_realloc_ = true;
+ tag_modified();
+ }
+
+ size_t size() const
{
return data_size;
}
@@ -432,7 +480,24 @@ template<typename T> class device_vector : public device_memory {
void copy_to_device()
{
- device_copy_to();
+ if (data_size != 0) {
+ device_copy_to();
+ }
+ }
+
+ void copy_to_device_if_modified()
+ {
+ if (!modified) {
+ return;
+ }
+
+ copy_to_device();
+ }
+
+ void clear_modified()
+ {
+ modified = false;
+ need_realloc_ = false;
}
void copy_from_device()
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 44959577fb5..b272e59f99d 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -296,7 +296,7 @@ class MultiDevice : public Device {
i++;
}
- /* Change geomtry BVH pointers back to the multi BVH */
+ /* Change geometry BVH pointers back to the multi BVH. */
for (size_t k = 0; k < bvh->geometry.size(); ++k) {
bvh->geometry[k]->bvh = geom_bvhs[k];
}
diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h
index e74c4508ab6..b3a0f6daa57 100644
--- a/intern/cycles/device/device_network.h
+++ b/intern/cycles/device/device_network.h
@@ -80,7 +80,7 @@ class network_device_memory : public device_memory {
vector<char> local_data;
};
-/* Common netowrk error function / object for both DeviceNetwork and DeviceServer*/
+/* Common network error function / object for both DeviceNetwork and DeviceServer. */
class NetworkError {
public:
NetworkError()
diff --git a/intern/cycles/device/opencl/device_opencl.h b/intern/cycles/device/opencl/device_opencl.h
index 4fd3c27f17e..2d6c6d04214 100644
--- a/intern/cycles/device/opencl/device_opencl.h
+++ b/intern/cycles/device/opencl/device_opencl.h
@@ -34,7 +34,7 @@ CCL_NAMESPACE_BEGIN
/* Disable workarounds, seems to be working fine on latest drivers. */
# define CYCLES_DISABLE_DRIVER_WORKAROUNDS
-/* Define CYCLES_DISABLE_DRIVER_WORKAROUNDS to disable workaounds for testing */
+/* Define CYCLES_DISABLE_DRIVER_WORKAROUNDS to disable workarounds for testing. */
# ifndef CYCLES_DISABLE_DRIVER_WORKAROUNDS
/* Work around AMD driver hangs by ensuring each command is finished before doing anything else. */
# undef clEnqueueNDRangeKernel
@@ -287,7 +287,7 @@ class OpenCLDevice : public Device {
/* Try to load the program from device cache or disk */
bool load();
- /* Compile the kernel (first separate, failback to local) */
+ /* Compile the kernel (first separate, fail-back to local). */
void compile();
/* Create the OpenCL kernels after loading or compiling */
void create_kernels();
@@ -628,7 +628,7 @@ class OpenCLDevice : public Device {
void release_mem_object_safe(cl_mem mem);
void release_program_safe(cl_program program);
- /* ** Those guys are for workign around some compiler-specific bugs ** */
+ /* ** Those guys are for working around some compiler-specific bugs ** */
cl_program load_cached_kernel(ustring key, thread_scoped_lock &cache_locker);
diff --git a/intern/cycles/device/opencl/device_opencl_impl.cpp b/intern/cycles/device/opencl/device_opencl_impl.cpp
index ec699462bfe..aee3b0fb64f 100644
--- a/intern/cycles/device/opencl/device_opencl_impl.cpp
+++ b/intern/cycles/device/opencl/device_opencl_impl.cpp
@@ -2151,7 +2151,7 @@ void OpenCLDevice::release_program_safe(cl_program program)
}
}
-/* ** Those guys are for workign around some compiler-specific bugs ** */
+/* ** Those guys are for working around some compiler-specific bugs ** */
cl_program OpenCLDevice::load_cached_kernel(ustring key, thread_scoped_lock &cache_locker)
{
diff --git a/intern/cycles/kernel/bvh/bvh_types.h b/intern/cycles/kernel/bvh/bvh_types.h
index b173568266b..9f0879a2069 100644
--- a/intern/cycles/kernel/bvh/bvh_types.h
+++ b/intern/cycles/kernel/bvh/bvh_types.h
@@ -42,7 +42,7 @@ CCL_NAMESPACE_BEGIN
#define BVH_FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
-/* Debugging heleprs */
+/* Debugging helpers. */
#ifdef __KERNEL_DEBUG__
# define BVH_DEBUG_INIT() \
do { \
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index d9e81535b62..32639ba24ec 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -125,7 +125,7 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals *kg,
}
*slope_y = fast_ierff(2.0f * randv - 1.0f);
#else
- /* Use precomputed table on CPU, it gives better perfomance. */
+ /* Use precomputed table on CPU, it gives better performance. */
int beckmann_table_offset = kernel_data.tables.beckmann_offset;
*slope_x = lookup_table_read_2D(
diff --git a/intern/cycles/kernel/filter/filter_transform_gpu.h b/intern/cycles/kernel/filter/filter_transform_gpu.h
index adc85881fe5..ec258a5212a 100644
--- a/intern/cycles/kernel/filter/filter_transform_gpu.h
+++ b/intern/cycles/kernel/filter/filter_transform_gpu.h
@@ -78,7 +78,7 @@ ccl_device void kernel_filter_construct_transform(const ccl_global float *ccl_re
/* === Generate the feature transformation. ===
* This transformation maps the num_features-dimensional feature space to a reduced feature
* (r-feature) space which generally has fewer dimensions.
- * This mainly helps to prevent overfitting. */
+ * This mainly helps to prevent over-fitting. */
float feature_matrix[DENOISE_FEATURES * DENOISE_FEATURES];
math_matrix_zero(feature_matrix, num_features);
FOR_PIXEL_WINDOW
@@ -91,7 +91,7 @@ ccl_device void kernel_filter_construct_transform(const ccl_global float *ccl_re
math_matrix_jacobi_eigendecomposition(feature_matrix, transform, num_features, transform_stride);
*rank = 0;
- /* Prevent overfitting when a small window is used. */
+ /* Prevent over-fitting when a small window is used. */
int max_rank = min(num_features, num_pixels / 3);
if (pca_threshold < 0.0f) {
float threshold_energy = 0.0f;
diff --git a/intern/cycles/kernel/filter/filter_transform_sse.h b/intern/cycles/kernel/filter/filter_transform_sse.h
index 5a124b5d73b..0304d990f9f 100644
--- a/intern/cycles/kernel/filter/filter_transform_sse.h
+++ b/intern/cycles/kernel/filter/filter_transform_sse.h
@@ -93,7 +93,7 @@ ccl_device void kernel_filter_construct_transform(const float *ccl_restrict buff
math_matrix_jacobi_eigendecomposition(feature_matrix, transform, num_features, 1);
*rank = 0;
- /* Prevent overfitting when a small window is used. */
+ /* Prevent over-fitting when a small window is used. */
int max_rank = min(num_features, num_pixels / 3);
if (pca_threshold < 0.0f) {
float threshold_energy = 0.0f;
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index 1907f5d3935..fe73335a335 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -435,7 +435,7 @@ ccl_device_inline float bvh_instance_push(
return t;
}
-/* Transorm ray to exit static object in BVH */
+/* Transform ray to exit static object in BVH. */
ccl_device_inline float bvh_instance_pop(
KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float t)
@@ -497,7 +497,7 @@ ccl_device_inline float bvh_instance_motion_push(KernelGlobals *kg,
return t;
}
-/* Transorm ray to exit motion blurred object in BVH */
+/* Transform ray to exit motion blurred object in BVH. */
ccl_device_inline float bvh_instance_motion_pop(KernelGlobals *kg,
int object,
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index e876e5d8ca6..ddcf94be1de 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -251,7 +251,7 @@ ccl_device void kernel_bake_evaluate(
path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y);
}
- /* Barycentric UV with subpixel offset. */
+ /* Barycentric UV with sub-pixel offset. */
float u = primitive[2];
float v = primitive[3];
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index 17b69b6198b..a6fd4f1dc7e 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -63,12 +63,12 @@ ccl_device float4 film_map(KernelGlobals *kg, float4 rgba_in, float scale)
{
float4 result;
- /* conversion to srgb */
+ /* Conversion to SRGB. */
result.x = color_linear_to_srgb(rgba_in.x * scale);
result.y = color_linear_to_srgb(rgba_in.y * scale);
result.z = color_linear_to_srgb(rgba_in.z * scale);
- /* clamp since alpha might be > 1.0 due to russian roulette */
+ /* Clamp since alpha might be > 1.0 due to Russian roulette. */
result.w = saturate(rgba_in.w * scale);
return result;
diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h
index b9c48b86a5d..f4e60a807f7 100644
--- a/intern/cycles/kernel/kernel_jitter.h
+++ b/intern/cycles/kernel/kernel_jitter.h
@@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN
/* "Correlated Multi-Jittered Sampling"
* Andrew Kensler, Pixar Technical Memo 13-01, 2013 */
-/* todo: find good value, suggested 64 gives pattern on cornell box ceiling */
+/* TODO: find good value, suggested 64 gives pattern on cornell box ceiling. */
#define CMJ_RANDOM_OFFSET_LIMIT 4096
ccl_device_inline bool cmj_is_pow2(int i)
@@ -179,7 +179,7 @@ ccl_device void cmj_sample_2D(int s, int N, int p, float *fx, float *fy)
smodm = cmj_fast_mod_pow2(s, m);
}
else {
- /* Doing s*inmv gives precision issues here. */
+ /* Doing `s * inmv` gives precision issues here. */
sdivm = s / m;
smodm = s - sdivm * m;
}
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index b9569f531e6..9ce7a147369 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -155,7 +155,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
else
# endif /* __VOLUME_DECOUPLED__ */
{
- /* GPU: no decoupled ray marching, scatter probalistically */
+ /* GPU: no decoupled ray marching, scatter probabilistically. */
int num_samples = kernel_data.integrator.volume_samples;
float num_samples_inv = 1.0f / num_samples;
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h
index a9b17854f25..49e5e25c2e0 100644
--- a/intern/cycles/kernel/kernel_random.h
+++ b/intern/cycles/kernel/kernel_random.h
@@ -304,7 +304,7 @@ ccl_device_inline bool sample_is_even(int pattern, int sample)
#elif defined(__KERNEL_OPENCL__)
return popcount(sample & 0xaaaaaaaa) & 1;
#else
- /* TODO(Stefan): popcnt intrinsic for Windows with fallback for older CPUs. */
+ /* TODO(Stefan): pop-count intrinsic for Windows with fallback for older CPUs. */
int i = sample & 0xaaaaaaaa;
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index f0e65542693..82cc11922e0 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1641,7 +1641,7 @@ enum RayState {
RAY_UPDATE_BUFFER,
/* Denotes ray needs to skip most surface shader work. */
RAY_HAS_ONLY_VOLUME,
- /* Donotes ray has hit background */
+ /* Denotes ray has hit background */
RAY_HIT_BACKGROUND,
/* Denotes ray has to be regenerated */
RAY_TO_REGENERATE,
@@ -1699,7 +1699,7 @@ typedef struct WorkTile {
ccl_global float *buffer;
} WorkTile;
-/* Precoumputed sample table sizes for PMJ02 sampler. */
+/* Pre-computed sample table sizes for PMJ02 sampler. */
#define NUM_PMJ_SAMPLES 64 * 64
#define NUM_PMJ_PATTERNS 48
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
index d87e5f193ad..bb6b8a40e8e 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
+++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h
@@ -18,7 +18,7 @@
/* Data type to replace `double` used in the NanoVDB headers. Cycles don't need doubles, and is
* safer and more portable to never use double datatype on GPU.
* Use a special structure, so that the following is true:
- * - No unnoticed implicit cast or mathermatical operations used on scalar 64bit type
+ * - No unnoticed implicit cast or mathematical operations used on scalar 64bit type
* (which rules out trick like using `uint64_t` as a drop-in replacement for double).
* - Padding rules are matching exactly `double`
* (which rules out array of `uint8_t`). */
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index caca3c28c8d..f1789f0d7eb 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -43,7 +43,7 @@ class ColorSpaceProcessor;
*
* Data needed by OSL render services, that is global to a rendering session.
* This includes all OSL shaders, name to attribute mapping and texture handles.
- * */
+ */
struct OSLGlobals {
OSLGlobals()
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 2a4a1dfe325..2b7c21d0bc4 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -1033,7 +1033,7 @@ bool OSLRenderServices::get_background_attribute(
return set_attribute_int(f, type, derivatives, val);
}
else if (name == u_ndc) {
- /* NDC coordinates with special exception for otho */
+ /* NDC coordinates with special exception for orthographic projection. */
OSLThreadData *tdata = kg->osl_tdata;
OSL::ShaderGlobals *globals = &tdata->globals;
float3 ndc[3];
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 3d0813c15e3..8606c459375 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -129,7 +129,7 @@ static void shaderdata_to_shaderglobals(
/* clear trace data */
tdata->tracedata.init = false;
- /* used by renderservices */
+ /* Used by render-services. */
sd->osl_globals = kg;
sd->osl_path_state = state;
}
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index 22d34a1082c..9e2ef84c872 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -42,7 +42,7 @@ point map_to_sphere(vector dir)
float v, u;
if (len > 0.0) {
if (dir[0] == 0.0 && dir[1] == 0.0) {
- u = 0.0; /* Othwise domain error. */
+ u = 0.0; /* Otherwise domain error. */
}
else {
u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0;
diff --git a/intern/cycles/kernel/split/kernel_branched.h b/intern/cycles/kernel/split/kernel_branched.h
index bfcd21baac4..45f5037d321 100644
--- a/intern/cycles/kernel/split/kernel_branched.h
+++ b/intern/cycles/kernel/split/kernel_branched.h
@@ -41,7 +41,7 @@ ccl_device_inline void kernel_split_branched_path_indirect_loop_init(KernelGloba
# undef BRANCHED_STORE
- /* set loop counters to intial position */
+ /* Set loop counters to initial position. */
branched_state->next_closure = 0;
branched_state->next_sample = 0;
}
diff --git a/intern/cycles/kernel/split/kernel_do_volume.h b/intern/cycles/kernel/split/kernel_do_volume.h
index b24699ec39c..1775e870f07 100644
--- a/intern/cycles/kernel/split/kernel_do_volume.h
+++ b/intern/cycles/kernel/split/kernel_do_volume.h
@@ -35,7 +35,7 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
ShaderData *emission_sd = AS_SHADER_DATA(&kernel_split_state.sd_DL_shadow[ray_index]);
- /* GPU: no decoupled ray marching, scatter probalistically */
+ /* GPU: no decoupled ray marching, scatter probabilistically. */
int num_samples = kernel_data.integrator.volume_samples;
float num_samples_inv = 1.0f / num_samples;
diff --git a/intern/cycles/kernel/split/kernel_enqueue_inactive.h b/intern/cycles/kernel/split/kernel_enqueue_inactive.h
index 31d2daef616..745313f89f1 100644
--- a/intern/cycles/kernel/split/kernel_enqueue_inactive.h
+++ b/intern/cycles/kernel/split/kernel_enqueue_inactive.h
@@ -20,7 +20,7 @@ ccl_device void kernel_enqueue_inactive(KernelGlobals *kg,
ccl_local_param unsigned int *local_queue_atomics)
{
#ifdef __BRANCHED_PATH__
- /* Enqeueue RAY_INACTIVE rays into QUEUE_INACTIVE_RAYS queue. */
+ /* Enqueue RAY_INACTIVE rays into QUEUE_INACTIVE_RAYS queue. */
if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
*local_queue_atomics = 0;
}
diff --git a/intern/cycles/kernel/split/kernel_shader_setup.h b/intern/cycles/kernel/split/kernel_shader_setup.h
index 900cbcb869c..551836d1653 100644
--- a/intern/cycles/kernel/split/kernel_shader_setup.h
+++ b/intern/cycles/kernel/split/kernel_shader_setup.h
@@ -25,7 +25,7 @@ CCL_NAMESPACE_BEGIN
ccl_device void kernel_shader_setup(KernelGlobals *kg,
ccl_local_param unsigned int *local_queue_atomics)
{
- /* Enqeueue RAY_TO_REGENERATE rays into QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS queue. */
+ /* Enqueue RAY_TO_REGENERATE rays into QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS queue. */
if (ccl_local_id(0) == 0 && ccl_local_id(1) == 0) {
*local_queue_atomics = 0;
}
diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h
index 1f7bd421869..c299cf58c7f 100644
--- a/intern/cycles/kernel/svm/svm_hsv.h
+++ b/intern/cycles/kernel/svm/svm_hsv.h
@@ -37,7 +37,7 @@ ccl_device void svm_node_hsv(
color = rgb_to_hsv(color);
- /* remember: fmod doesn't work for negative numbers here */
+ /* Remember: `fmodf` doesn't work for negative numbers here. */
color.x = fmodf(color.x + hue + 0.5f, 1.0f);
color.y = saturate(color.y * sat);
color.z *= val;
@@ -48,7 +48,7 @@ ccl_device void svm_node_hsv(
color.y = fac * color.y + (1.0f - fac) * in_color.y;
color.z = fac * color.z + (1.0f - fac) * in_color.z;
- /* Clamp color to prevent negative values caused by oversaturation. */
+ /* Clamp color to prevent negative values caused by over saturation. */
color.x = max(color.x, 0.0f);
color.y = max(color.y, 0.0f);
color.z = max(color.z, 0.0f);
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index f57c85fc23e..742addab611 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -38,7 +38,7 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
return r;
}
-/* Remap coordnate from 0..1 box to -1..-1 */
+/* Remap coordinate from 0..1 box to -1..-1 */
ccl_device_inline float3 texco_remap_square(float3 co)
{
return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h
index 7db8ffcc6e1..7ad61f23cc1 100644
--- a/intern/cycles/kernel/svm/svm_noise.h
+++ b/intern/cycles/kernel/svm/svm_noise.h
@@ -615,8 +615,8 @@ ccl_device_noinline float perlin_3d(float x, float y, float z)
*
* Point Offset from v0
* v0 (0, 0, 0, 0)
- * v1 (0, 0, 1, 0) The full avx type is computed by inserting the following
- * v2 (0, 1, 0, 0) sse types into both the low and high parts of the avx.
+ * v1 (0, 0, 1, 0) The full AVX type is computed by inserting the following
+ * v2 (0, 1, 0, 0) sse types into both the low and high parts of the AVX.
* v3 (0, 1, 1, 0)
* v4 (1, 0, 0, 0)
* v5 (1, 0, 1, 0) (0, 1, 0, 1) = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(V, V + 1))
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index c228df14985..4a00afc1d7f 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -205,8 +205,8 @@ typedef enum NodeHairInfo {
NODE_INFO_CURVE_IS_STRAND,
NODE_INFO_CURVE_INTERCEPT,
NODE_INFO_CURVE_THICKNESS,
- /*fade for minimum hair width transpency*/
- /*NODE_INFO_CURVE_FADE,*/
+ /* Fade for minimum hair width transiency. */
+ // NODE_INFO_CURVE_FADE,
NODE_INFO_CURVE_TANGENT_NORMAL,
NODE_INFO_CURVE_RANDOM,
} NodeHairInfo;
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index 9663e25cd93..389f913b145 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC_SYS
)
set(SRC
+ alembic.cpp
attribute.cpp
background.cpp
bake.cpp
@@ -48,6 +49,7 @@ set(SRC
mesh_displace.cpp
mesh_subdivision.cpp
nodes.cpp
+ procedural.cpp
object.cpp
osl.cpp
particles.cpp
@@ -64,6 +66,7 @@ set(SRC
)
set(SRC_HEADERS
+ alembic.h
attribute.h
bake.h
background.h
@@ -90,6 +93,7 @@ set(SRC_HEADERS
object.h
osl.h
particles.h
+ procedural.h
curves.h
scene.h
session.h
@@ -144,6 +148,16 @@ if(WITH_OPENVDB)
)
endif()
+if(WITH_ALEMBIC)
+ add_definitions(-DWITH_ALEMBIC)
+ list(APPEND INC_SYS
+ ${ALEMBIC_INCLUDE_DIRS}
+ )
+ list(APPEND LIB
+ ${ALEMBIC_LIBRARIES}
+ )
+endif()
+
if(WITH_NANOVDB)
list(APPEND INC_SYS
${NANOVDB_INCLUDE_DIRS}
diff --git a/intern/cycles/render/alembic.cpp b/intern/cycles/render/alembic.cpp
new file mode 100644
index 00000000000..5942e512e60
--- /dev/null
+++ b/intern/cycles/render/alembic.cpp
@@ -0,0 +1,1881 @@
+/*
+ * Copyright 2011-2018 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "render/alembic.h"
+
+#include "render/camera.h"
+#include "render/curves.h"
+#include "render/mesh.h"
+#include "render/object.h"
+#include "render/scene.h"
+#include "render/shader.h"
+
+#include "util/util_foreach.h"
+#include "util/util_progress.h"
+#include "util/util_transform.h"
+#include "util/util_vector.h"
+
+#ifdef WITH_ALEMBIC
+
+using namespace Alembic::AbcGeom;
+
+CCL_NAMESPACE_BEGIN
+
+/* TODO(@kevindietrich): motion blur support */
+
+void CachedData::clear()
+{
+ attributes.clear();
+ curve_first_key.clear();
+ curve_keys.clear();
+ curve_radius.clear();
+ curve_shader.clear();
+ num_ngons.clear();
+ shader.clear();
+ subd_creases_edge.clear();
+ subd_creases_weight.clear();
+ subd_face_corners.clear();
+ subd_num_corners.clear();
+ subd_ptex_offset.clear();
+ subd_smooth.clear();
+ subd_start_corner.clear();
+ transforms.clear();
+ triangles.clear();
+ triangles_loops.clear();
+ vertices.clear();
+
+ for (CachedAttribute &attr : attributes) {
+ attr.data.clear();
+ }
+
+ attributes.clear();
+}
+
+CachedData::CachedAttribute &CachedData::add_attribute(const ustring &name,
+ const TimeSampling &time_sampling)
+{
+ for (auto &attr : attributes) {
+ if (attr.name == name) {
+ return attr;
+ }
+ }
+
+ CachedAttribute &attr = attributes.emplace_back();
+ attr.name = name;
+ attr.data.set_time_sampling(time_sampling);
+ return attr;
+}
+
+bool CachedData::is_constant() const
+{
+# define CHECK_IF_CONSTANT(data) \
+ if (!data.is_constant()) { \
+ return false; \
+ }
+
+ CHECK_IF_CONSTANT(curve_first_key)
+ CHECK_IF_CONSTANT(curve_keys)
+ CHECK_IF_CONSTANT(curve_radius)
+ CHECK_IF_CONSTANT(curve_shader)
+ CHECK_IF_CONSTANT(num_ngons)
+ CHECK_IF_CONSTANT(shader)
+ CHECK_IF_CONSTANT(subd_creases_edge)
+ CHECK_IF_CONSTANT(subd_creases_weight)
+ CHECK_IF_CONSTANT(subd_face_corners)
+ CHECK_IF_CONSTANT(subd_num_corners)
+ CHECK_IF_CONSTANT(subd_ptex_offset)
+ CHECK_IF_CONSTANT(subd_smooth)
+ CHECK_IF_CONSTANT(subd_start_corner)
+ CHECK_IF_CONSTANT(transforms)
+ CHECK_IF_CONSTANT(triangles)
+ CHECK_IF_CONSTANT(triangles_loops)
+ CHECK_IF_CONSTANT(vertices)
+
+ for (const CachedAttribute &attr : attributes) {
+ if (!attr.data.is_constant()) {
+ return false;
+ }
+ }
+
+ return true;
+
+# undef CHECK_IF_CONSTANT
+}
+
+void CachedData::invalidate_last_loaded_time(bool attributes_only)
+{
+ if (attributes_only) {
+ for (CachedAttribute &attr : attributes) {
+ attr.data.invalidate_last_loaded_time();
+ }
+
+ return;
+ }
+
+ curve_first_key.invalidate_last_loaded_time();
+ curve_keys.invalidate_last_loaded_time();
+ curve_radius.invalidate_last_loaded_time();
+ curve_shader.invalidate_last_loaded_time();
+ num_ngons.invalidate_last_loaded_time();
+ shader.invalidate_last_loaded_time();
+ subd_creases_edge.invalidate_last_loaded_time();
+ subd_creases_weight.invalidate_last_loaded_time();
+ subd_face_corners.invalidate_last_loaded_time();
+ subd_num_corners.invalidate_last_loaded_time();
+ subd_ptex_offset.invalidate_last_loaded_time();
+ subd_smooth.invalidate_last_loaded_time();
+ subd_start_corner.invalidate_last_loaded_time();
+ transforms.invalidate_last_loaded_time();
+ triangles.invalidate_last_loaded_time();
+ triangles_loops.invalidate_last_loaded_time();
+ vertices.invalidate_last_loaded_time();
+}
+
+void CachedData::set_time_sampling(TimeSampling time_sampling)
+{
+ curve_first_key.set_time_sampling(time_sampling);
+ curve_keys.set_time_sampling(time_sampling);
+ curve_radius.set_time_sampling(time_sampling);
+ curve_shader.set_time_sampling(time_sampling);
+ num_ngons.set_time_sampling(time_sampling);
+ shader.set_time_sampling(time_sampling);
+ subd_creases_edge.set_time_sampling(time_sampling);
+ subd_creases_weight.set_time_sampling(time_sampling);
+ subd_face_corners.set_time_sampling(time_sampling);
+ subd_num_corners.set_time_sampling(time_sampling);
+ subd_ptex_offset.set_time_sampling(time_sampling);
+ subd_smooth.set_time_sampling(time_sampling);
+ subd_start_corner.set_time_sampling(time_sampling);
+ transforms.set_time_sampling(time_sampling);
+ triangles.set_time_sampling(time_sampling);
+ triangles_loops.set_time_sampling(time_sampling);
+ vertices.set_time_sampling(time_sampling);
+
+ for (CachedAttribute &attr : attributes) {
+ attr.data.set_time_sampling(time_sampling);
+ }
+}
+
+/* get the sample times to load data for the given the start and end frame of the procedural */
+static set<chrono_t> get_relevant_sample_times(AlembicProcedural *proc,
+ const TimeSampling &time_sampling,
+ size_t num_samples)
+{
+ set<chrono_t> result;
+
+ if (num_samples < 2) {
+ result.insert(0.0);
+ return result;
+ }
+
+ double start_frame = (double)(proc->get_start_frame() / proc->get_frame_rate());
+ double end_frame = (double)((proc->get_end_frame() + 1) / proc->get_frame_rate());
+
+ size_t start_index = time_sampling.getFloorIndex(start_frame, num_samples).first;
+ size_t end_index = time_sampling.getCeilIndex(end_frame, num_samples).first;
+
+ for (size_t i = start_index; i < end_index; ++i) {
+ result.insert(time_sampling.getSampleTime(i));
+ }
+
+ return result;
+}
+
+static float3 make_float3_from_yup(const V3f &v)
+{
+ return make_float3(v.x, -v.z, v.y);
+}
+
+static M44d convert_yup_zup(const M44d &mtx, float scale_mult)
+{
+ V3d scale, shear, rotation, translation;
+ extractSHRT(mtx,
+ scale,
+ shear,
+ rotation,
+ translation,
+ true,
+ IMATH_INTERNAL_NAMESPACE::Euler<double>::XZY);
+
+ M44d rot_mat, scale_mat, trans_mat;
+ rot_mat.setEulerAngles(V3d(rotation.x, -rotation.z, rotation.y));
+ scale_mat.setScale(V3d(scale.x, scale.z, scale.y));
+ trans_mat.setTranslation(V3d(translation.x, -translation.z, translation.y));
+
+ M44d temp_mat = scale_mat * rot_mat * trans_mat;
+
+ scale_mat.setScale(static_cast<double>(scale_mult));
+
+ return temp_mat * scale_mat;
+}
+
+static void transform_decompose(
+ const M44d &mat, V3d &scale, V3d &shear, Quatd &rotation, V3d &translation)
+{
+ M44d mat_remainder(mat);
+
+ /* extract scale and shear */
+ Imath::extractAndRemoveScalingAndShear(mat_remainder, scale, shear);
+
+ /* extract translation */
+ translation.x = mat_remainder[3][0];
+ translation.y = mat_remainder[3][1];
+ translation.z = mat_remainder[3][2];
+
+ /* extract rotation */
+ rotation = extractQuat(mat_remainder);
+}
+
+static M44d transform_compose(const V3d &scale,
+ const V3d &shear,
+ const Quatd &rotation,
+ const V3d &translation)
+{
+ M44d scale_mat, shear_mat, rot_mat, trans_mat;
+
+ scale_mat.setScale(scale);
+ shear_mat.setShear(shear);
+ rot_mat = rotation.toMatrix44();
+ trans_mat.setTranslation(translation);
+
+ return scale_mat * shear_mat * rot_mat * trans_mat;
+}
+
+/* get the matrix for the specified time, or return the identity matrix if there is no exact match
+ */
+static M44d get_matrix_for_time(const MatrixSampleMap &samples, chrono_t time)
+{
+ MatrixSampleMap::const_iterator iter = samples.find(time);
+ if (iter != samples.end()) {
+ return iter->second;
+ }
+
+ return M44d();
+}
+
+/* get the matrix for the specified time, or interpolate between samples if there is no exact match
+ */
+static M44d get_interpolated_matrix_for_time(const MatrixSampleMap &samples, chrono_t time)
+{
+ if (samples.empty()) {
+ return M44d();
+ }
+
+ /* see if exact match */
+ MatrixSampleMap::const_iterator iter = samples.find(time);
+ if (iter != samples.end()) {
+ return iter->second;
+ }
+
+ if (samples.size() == 1) {
+ return samples.begin()->second;
+ }
+
+ if (time <= samples.begin()->first) {
+ return samples.begin()->second;
+ }
+
+ if (time >= samples.rbegin()->first) {
+ return samples.rbegin()->second;
+ }
+
+ /* find previous and next time sample to interpolate */
+ chrono_t prev_time = samples.begin()->first;
+ chrono_t next_time = samples.rbegin()->first;
+
+ for (MatrixSampleMap::const_iterator I = samples.begin(); I != samples.end(); ++I) {
+ chrono_t current_time = (*I).first;
+
+ if (current_time > prev_time && current_time <= time) {
+ prev_time = current_time;
+ }
+
+ if (current_time > next_time && current_time >= time) {
+ next_time = current_time;
+ }
+ }
+
+ const M44d prev_mat = get_matrix_for_time(samples, prev_time);
+ const M44d next_mat = get_matrix_for_time(samples, next_time);
+
+ V3d prev_scale, next_scale;
+ V3d prev_shear, next_shear;
+ V3d prev_translation, next_translation;
+ Quatd prev_rotation, next_rotation;
+
+ transform_decompose(prev_mat, prev_scale, prev_shear, prev_rotation, prev_translation);
+ transform_decompose(next_mat, next_scale, next_shear, next_rotation, next_translation);
+
+ chrono_t t = (time - prev_time) / (next_time - prev_time);
+
+ /* ensure rotation around the shortest angle */
+ if ((prev_rotation ^ next_rotation) < 0) {
+ next_rotation = -next_rotation;
+ }
+
+ return transform_compose(Imath::lerp(prev_scale, next_scale, t),
+ Imath::lerp(prev_shear, next_shear, t),
+ Imath::slerp(prev_rotation, next_rotation, t),
+ Imath::lerp(prev_translation, next_translation, t));
+}
+
+static void concatenate_xform_samples(const MatrixSampleMap &parent_samples,
+ const MatrixSampleMap &local_samples,
+ MatrixSampleMap &output_samples)
+{
+ set<chrono_t> union_of_samples;
+
+ for (const std::pair<chrono_t, M44d> pair : parent_samples) {
+ union_of_samples.insert(pair.first);
+ }
+
+ for (const std::pair<chrono_t, M44d> pair : local_samples) {
+ union_of_samples.insert(pair.first);
+ }
+
+ foreach (chrono_t time, union_of_samples) {
+ M44d parent_matrix = get_interpolated_matrix_for_time(parent_samples, time);
+ M44d local_matrix = get_interpolated_matrix_for_time(local_samples, time);
+
+ output_samples[time] = local_matrix * parent_matrix;
+ }
+}
+
+static Transform make_transform(const M44d &a, float scale)
+{
+ M44d m = convert_yup_zup(a, scale);
+ Transform trans;
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 4; i++) {
+ trans[j][i] = static_cast<float>(m[i][j]);
+ }
+ }
+ return trans;
+}
+
+static void add_uvs(AlembicProcedural *proc,
+ const IV2fGeomParam &uvs,
+ CachedData &cached_data,
+ Progress &progress)
+{
+ if (uvs.getScope() != kFacevaryingScope) {
+ return;
+ }
+
+ const TimeSamplingPtr time_sampling_ptr = uvs.getTimeSampling();
+
+ TimeSampling time_sampling;
+ if (time_sampling_ptr) {
+ time_sampling = *time_sampling_ptr;
+ }
+
+ std::string name = Alembic::Abc::GetSourceName(uvs.getMetaData());
+
+ /* According to the convention, primary UVs should have had their name
+ * set using Alembic::Abc::SetSourceName, but you can't expect everyone
+ * to follow it! :) */
+ if (name.empty()) {
+ name = uvs.getName();
+ }
+
+ CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(name), time_sampling);
+ attr.std = ATTR_STD_UV;
+
+ ccl::set<chrono_t> times = get_relevant_sample_times(proc, time_sampling, uvs.getNumSamples());
+
+ foreach (chrono_t time, times) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ const ISampleSelector iss = ISampleSelector(time);
+ const IV2fGeomParam::Sample sample = uvs.getExpandedValue(iss);
+
+ const IV2fGeomParam::Sample uvsample = uvs.getIndexedValue(iss);
+
+ if (!uvsample.valid()) {
+ continue;
+ }
+
+ const array<int3> *triangles = cached_data.triangles.data_for_time_no_check(time);
+ const array<int3> *triangles_loops = cached_data.triangles_loops.data_for_time_no_check(time);
+
+ if (!triangles || !triangles_loops) {
+ continue;
+ }
+
+ array<char> data;
+ data.resize(triangles->size() * 3 * sizeof(float2));
+
+ float2 *data_float2 = reinterpret_cast<float2 *>(data.data());
+
+ const unsigned int *indices = uvsample.getIndices()->get();
+ const V2f *values = uvsample.getVals()->get();
+
+ for (const int3 &loop : *triangles_loops) {
+ unsigned int v0 = indices[loop.x];
+ unsigned int v1 = indices[loop.y];
+ unsigned int v2 = indices[loop.z];
+
+ data_float2[0] = make_float2(values[v0][0], values[v0][1]);
+ data_float2[1] = make_float2(values[v1][0], values[v1][1]);
+ data_float2[2] = make_float2(values[v2][0], values[v2][1]);
+ data_float2 += 3;
+ }
+
+ attr.data.add_data(data, time);
+ }
+}
+
+static void add_normals(const Int32ArraySamplePtr face_indices,
+ const IN3fGeomParam &normals,
+ double time,
+ CachedData &cached_data)
+{
+ switch (normals.getScope()) {
+ case kFacevaryingScope: {
+ const ISampleSelector iss = ISampleSelector(time);
+ const IN3fGeomParam::Sample sample = normals.getExpandedValue(iss);
+
+ if (!sample.valid()) {
+ return;
+ }
+
+ CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(normals.getName()),
+ *normals.getTimeSampling());
+ attr.std = ATTR_STD_VERTEX_NORMAL;
+
+ const array<float3> *vertices = cached_data.vertices.data_for_time_no_check(time);
+
+ if (!vertices) {
+ return;
+ }
+
+ array<char> data;
+ data.resize(vertices->size() * sizeof(float3));
+
+ float3 *data_float3 = reinterpret_cast<float3 *>(data.data());
+
+ const int *face_indices_array = face_indices->get();
+ const N3fArraySamplePtr values = sample.getVals();
+
+ for (size_t i = 0; i < face_indices->size(); ++i) {
+ int point_index = face_indices_array[i];
+ data_float3[point_index] = make_float3_from_yup(values->get()[i]);
+ }
+
+ attr.data.add_data(data, time);
+ break;
+ }
+ case kVaryingScope:
+ case kVertexScope: {
+ const ISampleSelector iss = ISampleSelector(time);
+ const IN3fGeomParam::Sample sample = normals.getExpandedValue(iss);
+
+ if (!sample.valid()) {
+ return;
+ }
+
+ CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(normals.getName()),
+ *normals.getTimeSampling());
+ attr.std = ATTR_STD_VERTEX_NORMAL;
+
+ const array<float3> *vertices = cached_data.vertices.data_for_time_no_check(time);
+
+ if (!vertices) {
+ return;
+ }
+
+ array<char> data;
+ data.resize(vertices->size() * sizeof(float3));
+
+ float3 *data_float3 = reinterpret_cast<float3 *>(data.data());
+
+ const Imath::V3f *values = sample.getVals()->get();
+
+ for (size_t i = 0; i < vertices->size(); ++i) {
+ data_float3[i] = make_float3_from_yup(values[i]);
+ }
+
+ attr.data.add_data(data, time);
+
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+}
+
+static void add_positions(const P3fArraySamplePtr positions, double time, CachedData &cached_data)
+{
+ if (!positions) {
+ return;
+ }
+
+ array<float3> vertices;
+ vertices.reserve(positions->size());
+
+ for (size_t i = 0; i < positions->size(); i++) {
+ V3f f = positions->get()[i];
+ vertices.push_back_reserved(make_float3_from_yup(f));
+ }
+
+ cached_data.vertices.add_data(vertices, time);
+}
+
+static void add_triangles(const Int32ArraySamplePtr face_counts,
+ const Int32ArraySamplePtr face_indices,
+ double time,
+ CachedData &cached_data,
+ const array<int> &polygon_to_shader)
+{
+ if (!face_counts || !face_indices) {
+ return;
+ }
+
+ const size_t num_faces = face_counts->size();
+ const int *face_counts_array = face_counts->get();
+ const int *face_indices_array = face_indices->get();
+
+ size_t num_triangles = 0;
+ for (size_t i = 0; i < face_counts->size(); i++) {
+ num_triangles += face_counts_array[i] - 2;
+ }
+
+ array<int> shader;
+ array<int3> triangles;
+ array<int3> triangles_loops;
+ shader.reserve(num_triangles);
+ triangles.reserve(num_triangles);
+ triangles_loops.reserve(num_triangles);
+ int index_offset = 0;
+
+ for (size_t i = 0; i < num_faces; i++) {
+ int current_shader = 0;
+
+ if (!polygon_to_shader.empty()) {
+ current_shader = polygon_to_shader[i];
+ }
+
+ for (int j = 0; j < face_counts_array[i] - 2; j++) {
+ int v0 = face_indices_array[index_offset];
+ int v1 = face_indices_array[index_offset + j + 1];
+ int v2 = face_indices_array[index_offset + j + 2];
+
+ shader.push_back_reserved(current_shader);
+
+ /* Alembic orders the loops following the RenderMan convention, so need to go in reverse. */
+ triangles.push_back_reserved(make_int3(v2, v1, v0));
+ triangles_loops.push_back_reserved(
+ make_int3(index_offset + j + 2, index_offset + j + 1, index_offset));
+ }
+
+ index_offset += face_counts_array[i];
+ }
+
+ cached_data.triangles.add_data(triangles, time);
+ cached_data.triangles_loops.add_data(triangles_loops, time);
+ cached_data.shader.add_data(shader, time);
+}
+
+NODE_DEFINE(AlembicObject)
+{
+ NodeType *type = NodeType::add("alembic_object", create);
+
+ SOCKET_STRING(path, "Alembic Path", ustring());
+ SOCKET_NODE_ARRAY(used_shaders, "Used Shaders", &Shader::node_type);
+
+ SOCKET_INT(subd_max_level, "Max Subdivision Level", 1);
+ SOCKET_FLOAT(subd_dicing_rate, "Subdivision Dicing Rate", 1.0f);
+
+ SOCKET_FLOAT(radius_scale, "Radius Scale", 1.0f);
+
+ return type;
+}
+
+AlembicObject::AlembicObject() : Node(node_type)
+{
+}
+
+AlembicObject::~AlembicObject()
+{
+}
+
+void AlembicObject::set_object(Object *object_)
+{
+ object = object_;
+}
+
+Object *AlembicObject::get_object()
+{
+ return object;
+}
+
+bool AlembicObject::has_data_loaded() const
+{
+ return data_loaded;
+}
+
+void AlembicObject::update_shader_attributes(const ICompoundProperty &arb_geom_params,
+ Progress &progress)
+{
+ AttributeRequestSet requested_attributes = get_requested_attributes();
+
+ foreach (const AttributeRequest &attr, requested_attributes.requests) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ bool attr_exists = false;
+ foreach (CachedData::CachedAttribute &cached_attr, cached_data.attributes) {
+ if (cached_attr.name == attr.name) {
+ attr_exists = true;
+ break;
+ }
+ }
+
+ if (attr_exists) {
+ continue;
+ }
+
+ read_attribute(arb_geom_params, attr.name, progress);
+ }
+
+ cached_data.invalidate_last_loaded_time(true);
+ need_shader_update = false;
+}
+
+template<typename SchemaType>
+void AlembicObject::read_face_sets(SchemaType &schema,
+ array<int> &polygon_to_shader,
+ ISampleSelector sample_sel)
+{
+ std::vector<std::string> face_sets;
+ schema.getFaceSetNames(face_sets);
+
+ if (face_sets.empty()) {
+ return;
+ }
+
+ const Int32ArraySamplePtr face_counts = schema.getFaceCountsProperty().getValue();
+
+ polygon_to_shader.resize(face_counts->size());
+
+ foreach (const std::string &face_set_name, face_sets) {
+ int shader_index = 0;
+
+ foreach (Node *node, get_used_shaders()) {
+ if (node->name == face_set_name) {
+ break;
+ }
+
+ ++shader_index;
+ }
+
+ if (shader_index >= get_used_shaders().size()) {
+ /* use the first shader instead if none was found */
+ shader_index = 0;
+ }
+
+ const IFaceSet face_set = schema.getFaceSet(face_set_name);
+
+ if (!face_set.valid()) {
+ continue;
+ }
+
+ const IFaceSetSchema face_schem = face_set.getSchema();
+ const IFaceSetSchema::Sample face_sample = face_schem.getValue(sample_sel);
+ const Int32ArraySamplePtr group_faces = face_sample.getFaces();
+ const size_t num_group_faces = group_faces->size();
+
+ for (size_t l = 0; l < num_group_faces; l++) {
+ size_t pos = (*group_faces)[l];
+
+ if (pos >= polygon_to_shader.size()) {
+ continue;
+ }
+
+ polygon_to_shader[pos] = shader_index;
+ }
+ }
+}
+
+void AlembicObject::load_all_data(AlembicProcedural *proc,
+ IPolyMeshSchema &schema,
+ float scale,
+ Progress &progress)
+{
+ cached_data.clear();
+
+ const TimeSamplingPtr time_sampling = schema.getTimeSampling();
+ cached_data.set_time_sampling(*time_sampling);
+
+ const IN3fGeomParam &normals = schema.getNormalsParam();
+
+ ccl::set<chrono_t> times = get_relevant_sample_times(
+ proc, *time_sampling, schema.getNumSamples());
+
+ /* read topology */
+ foreach (chrono_t time, times) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ const ISampleSelector iss = ISampleSelector(time);
+ const IPolyMeshSchema::Sample sample = schema.getValue(iss);
+
+ add_positions(sample.getPositions(), time, cached_data);
+
+ /* Only copy triangles for other frames if the topology is changing over time as well.
+ *
+ * TODO(@kevindietrich): even for dynamic simulations, this is a waste of memory and
+ * processing time if only the positions are changing in a subsequence of frames but we
+ * cannot optimize in this current system if the attributes are changing over time as well,
+ * as we need valid data for each time point. This can be solved by using reference counting
+ * on the ccl::array and simply share the array across frames. */
+ if (schema.getTopologyVariance() != kHomogenousTopology || cached_data.triangles.size() == 0) {
+ /* start by reading the face sets (per face shader), as we directly split polygons to
+ * triangles
+ */
+ array<int> polygon_to_shader;
+ read_face_sets(schema, polygon_to_shader, iss);
+
+ add_triangles(
+ sample.getFaceCounts(), sample.getFaceIndices(), time, cached_data, polygon_to_shader);
+ }
+
+ if (normals.valid()) {
+ add_normals(sample.getFaceIndices(), normals, time, cached_data);
+ }
+ }
+
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ update_shader_attributes(schema.getArbGeomParams(), progress);
+
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ const IV2fGeomParam &uvs = schema.getUVsParam();
+
+ if (uvs.valid()) {
+ add_uvs(proc, uvs, cached_data, progress);
+ }
+
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ setup_transform_cache(scale);
+
+ data_loaded = true;
+}
+
+void AlembicObject::load_all_data(AlembicProcedural *proc,
+ ISubDSchema &schema,
+ float scale,
+ Progress &progress)
+{
+ cached_data.clear();
+
+ AttributeRequestSet requested_attributes = get_requested_attributes();
+
+ const TimeSamplingPtr time_sampling = schema.getTimeSampling();
+ cached_data.set_time_sampling(*time_sampling);
+
+ ccl::set<chrono_t> times = get_relevant_sample_times(
+ proc, *time_sampling, schema.getNumSamples());
+
+ /* read topology */
+ foreach (chrono_t time, times) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ const ISampleSelector iss = ISampleSelector(time);
+ const ISubDSchema::Sample sample = schema.getValue(iss);
+
+ add_positions(sample.getPositions(), time, cached_data);
+
+ const Int32ArraySamplePtr face_counts = sample.getFaceCounts();
+ const Int32ArraySamplePtr face_indices = sample.getFaceIndices();
+
+ /* start by reading the face sets (per face shader) */
+ array<int> polygon_to_shader;
+ read_face_sets(schema, polygon_to_shader, iss);
+
+ /* read faces */
+ array<int> subd_start_corner;
+ array<int> shader;
+ array<int> subd_num_corners;
+ array<bool> subd_smooth;
+ array<int> subd_ptex_offset;
+ array<int> subd_face_corners;
+
+ const size_t num_faces = face_counts->size();
+ const int *face_counts_array = face_counts->get();
+ const int *face_indices_array = face_indices->get();
+
+ int num_ngons = 0;
+ int num_corners = 0;
+ for (size_t i = 0; i < face_counts->size(); i++) {
+ num_ngons += (face_counts_array[i] == 4 ? 0 : 1);
+ num_corners += face_counts_array[i];
+ }
+
+ subd_start_corner.reserve(num_faces);
+ subd_num_corners.reserve(num_faces);
+ subd_smooth.reserve(num_faces);
+ subd_ptex_offset.reserve(num_faces);
+ shader.reserve(num_faces);
+ subd_face_corners.reserve(num_corners);
+
+ int start_corner = 0;
+ int current_shader = 0;
+ int ptex_offset = 0;
+
+ for (size_t i = 0; i < face_counts->size(); i++) {
+ num_corners = face_counts_array[i];
+
+ if (!polygon_to_shader.empty()) {
+ current_shader = polygon_to_shader[i];
+ }
+
+ subd_start_corner.push_back_reserved(start_corner);
+ subd_num_corners.push_back_reserved(num_corners);
+
+ for (int j = 0; j < num_corners; ++j) {
+ subd_face_corners.push_back_reserved(face_indices_array[start_corner + j]);
+ }
+
+ shader.push_back_reserved(current_shader);
+ subd_smooth.push_back_reserved(1);
+ subd_ptex_offset.push_back_reserved(ptex_offset);
+
+ ptex_offset += (num_corners == 4 ? 1 : num_corners);
+
+ start_corner += num_corners;
+ }
+
+ cached_data.shader.add_data(shader, time);
+ cached_data.subd_start_corner.add_data(subd_start_corner, time);
+ cached_data.subd_num_corners.add_data(subd_num_corners, time);
+ cached_data.subd_smooth.add_data(subd_smooth, time);
+ cached_data.subd_ptex_offset.add_data(subd_ptex_offset, time);
+ cached_data.subd_face_corners.add_data(subd_face_corners, time);
+ cached_data.num_ngons.add_data(num_ngons, time);
+
+ /* read creases */
+ Int32ArraySamplePtr creases_length = sample.getCreaseLengths();
+ Int32ArraySamplePtr creases_indices = sample.getCreaseIndices();
+ FloatArraySamplePtr creases_sharpnesses = sample.getCreaseSharpnesses();
+
+ if (creases_length && creases_indices && creases_sharpnesses) {
+ array<int> creases_edge;
+ array<float> creases_weight;
+
+ creases_edge.reserve(creases_sharpnesses->size() * 2);
+ creases_weight.reserve(creases_sharpnesses->size());
+
+ int length_offset = 0;
+ int weight_offset = 0;
+ for (size_t c = 0; c < creases_length->size(); ++c) {
+ const int crease_length = creases_length->get()[c];
+
+ for (size_t j = 0; j < crease_length - 1; ++j) {
+ creases_edge.push_back_reserved(creases_indices->get()[length_offset + j]);
+ creases_edge.push_back_reserved(creases_indices->get()[length_offset + j + 1]);
+ creases_weight.push_back_reserved(creases_sharpnesses->get()[weight_offset++]);
+ }
+
+ length_offset += crease_length;
+ }
+
+ cached_data.subd_creases_edge.add_data(creases_edge, time);
+ cached_data.subd_creases_weight.add_data(creases_weight, time);
+ }
+ }
+
+ /* TODO(@kevindietrich) : attributes, need test files */
+
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ setup_transform_cache(scale);
+
+ data_loaded = true;
+}
+
+void AlembicObject::load_all_data(AlembicProcedural *proc,
+ const ICurvesSchema &schema,
+ float scale,
+ Progress &progress,
+ float default_radius)
+{
+ cached_data.clear();
+
+ const TimeSamplingPtr time_sampling = schema.getTimeSampling();
+ cached_data.set_time_sampling(*time_sampling);
+
+ ccl::set<chrono_t> times = get_relevant_sample_times(
+ proc, *time_sampling, schema.getNumSamples());
+
+ foreach (chrono_t time, times) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ const ISampleSelector iss = ISampleSelector(time);
+ const ICurvesSchema::Sample sample = schema.getValue(iss);
+
+ const Int32ArraySamplePtr curves_num_vertices = sample.getCurvesNumVertices();
+ const P3fArraySamplePtr position = sample.getPositions();
+
+ const IFloatGeomParam widths_param = schema.getWidthsParam();
+ FloatArraySamplePtr radiuses;
+
+ if (widths_param.valid()) {
+ IFloatGeomParam::Sample wsample = widths_param.getExpandedValue(iss);
+ radiuses = wsample.getVals();
+ }
+
+ const bool do_radius = (radiuses != nullptr) && (radiuses->size() > 1);
+ float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] : default_radius;
+
+ array<float3> curve_keys;
+ array<float> curve_radius;
+ array<int> curve_first_key;
+ array<int> curve_shader;
+
+ curve_keys.reserve(position->size());
+ curve_radius.reserve(position->size());
+ curve_first_key.reserve(curves_num_vertices->size());
+ curve_shader.reserve(curves_num_vertices->size());
+
+ int offset = 0;
+ for (size_t i = 0; i < curves_num_vertices->size(); i++) {
+ const int num_vertices = curves_num_vertices->get()[i];
+
+ for (int j = 0; j < num_vertices; j++) {
+ const V3f &f = position->get()[offset + j];
+ curve_keys.push_back_reserved(make_float3_from_yup(f));
+
+ if (do_radius) {
+ radius = (*radiuses)[offset + j];
+ }
+
+ curve_radius.push_back_reserved(radius * radius_scale);
+ }
+
+ curve_first_key.push_back_reserved(offset);
+ curve_shader.push_back_reserved(0);
+
+ offset += num_vertices;
+ }
+
+ cached_data.curve_keys.add_data(curve_keys, time);
+ cached_data.curve_radius.add_data(curve_radius, time);
+ cached_data.curve_first_key.add_data(curve_first_key, time);
+ cached_data.curve_shader.add_data(curve_shader, time);
+ }
+
+ // TODO(@kevindietrich): attributes, need example files
+
+ setup_transform_cache(scale);
+
+ data_loaded = true;
+}
+
+void AlembicObject::setup_transform_cache(float scale)
+{
+ cached_data.transforms.clear();
+ cached_data.transforms.invalidate_last_loaded_time();
+
+ if (xform_samples.size() == 0) {
+ Transform tfm = transform_scale(make_float3(scale));
+ cached_data.transforms.add_data(tfm, 0.0);
+ }
+ else {
+ /* It is possible for a leaf node of the hierarchy to have multiple samples for its transforms
+ * if a sibling has animated transforms. So check if we indeed have animated transformations.
+ */
+ M44d first_matrix = xform_samples.begin()->first;
+ bool has_animation = false;
+ for (const std::pair<chrono_t, M44d> pair : xform_samples) {
+ if (pair.second != first_matrix) {
+ has_animation = true;
+ break;
+ }
+ }
+
+ if (!has_animation) {
+ Transform tfm = make_transform(first_matrix, scale);
+ cached_data.transforms.add_data(tfm, 0.0);
+ }
+ else {
+ for (const std::pair<chrono_t, M44d> pair : xform_samples) {
+ Transform tfm = make_transform(pair.second, scale);
+ cached_data.transforms.add_data(tfm, pair.first);
+ }
+ }
+ }
+}
+
+AttributeRequestSet AlembicObject::get_requested_attributes()
+{
+ AttributeRequestSet requested_attributes;
+
+ Geometry *geometry = object->get_geometry();
+ assert(geometry);
+
+ foreach (Node *node, geometry->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
+
+ foreach (const AttributeRequest &attr, shader->attributes.requests) {
+ if (attr.name != "") {
+ requested_attributes.add(attr.name);
+ }
+ }
+ }
+
+ return requested_attributes;
+}
+
+void AlembicObject::read_attribute(const ICompoundProperty &arb_geom_params,
+ const ustring &attr_name,
+ Progress &progress)
+{
+ const PropertyHeader *prop = arb_geom_params.getPropertyHeader(attr_name.c_str());
+
+ if (prop == nullptr) {
+ return;
+ }
+
+ if (IV2fProperty::matches(prop->getMetaData()) && Alembic::AbcGeom::isUV(*prop)) {
+ const IV2fGeomParam &param = IV2fGeomParam(arb_geom_params, prop->getName());
+
+ CachedData::CachedAttribute &attribute = cached_data.add_attribute(attr_name,
+ *param.getTimeSampling());
+
+ for (size_t i = 0; i < param.getNumSamples(); ++i) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ ISampleSelector iss = ISampleSelector(index_t(i));
+
+ IV2fGeomParam::Sample sample;
+ param.getIndexed(sample, iss);
+
+ const chrono_t time = param.getTimeSampling()->getSampleTime(index_t(i));
+
+ if (param.getScope() == kFacevaryingScope) {
+ V2fArraySamplePtr values = sample.getVals();
+ UInt32ArraySamplePtr indices = sample.getIndices();
+
+ attribute.std = ATTR_STD_NONE;
+ attribute.element = ATTR_ELEMENT_CORNER;
+ attribute.type_desc = TypeFloat2;
+
+ const array<int3> *triangles = cached_data.triangles.data_for_time_no_check(time);
+ const array<int3> *triangles_loops = cached_data.triangles_loops.data_for_time_no_check(
+ time);
+
+ if (!triangles || !triangles_loops) {
+ return;
+ }
+
+ array<char> data;
+ data.resize(triangles->size() * 3 * sizeof(float2));
+
+ float2 *data_float2 = reinterpret_cast<float2 *>(data.data());
+
+ for (const int3 &loop : *triangles_loops) {
+ unsigned int v0 = (*indices)[loop.x];
+ unsigned int v1 = (*indices)[loop.y];
+ unsigned int v2 = (*indices)[loop.z];
+
+ data_float2[0] = make_float2((*values)[v0][0], (*values)[v0][1]);
+ data_float2[1] = make_float2((*values)[v1][0], (*values)[v1][1]);
+ data_float2[2] = make_float2((*values)[v2][0], (*values)[v2][1]);
+ data_float2 += 3;
+ }
+
+ attribute.data.set_time_sampling(*param.getTimeSampling());
+ attribute.data.add_data(data, time);
+ }
+ }
+ }
+ else if (IC3fProperty::matches(prop->getMetaData())) {
+ const IC3fGeomParam &param = IC3fGeomParam(arb_geom_params, prop->getName());
+
+ CachedData::CachedAttribute &attribute = cached_data.add_attribute(attr_name,
+ *param.getTimeSampling());
+
+ for (size_t i = 0; i < param.getNumSamples(); ++i) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ ISampleSelector iss = ISampleSelector(index_t(i));
+
+ IC3fGeomParam::Sample sample;
+ param.getIndexed(sample, iss);
+
+ const chrono_t time = param.getTimeSampling()->getSampleTime(index_t(i));
+
+ C3fArraySamplePtr values = sample.getVals();
+
+ attribute.std = ATTR_STD_NONE;
+
+ if (param.getScope() == kVaryingScope) {
+ attribute.element = ATTR_ELEMENT_CORNER_BYTE;
+ attribute.type_desc = TypeRGBA;
+
+ const array<int3> *triangles = cached_data.triangles.data_for_time_no_check(time);
+
+ if (!triangles) {
+ return;
+ }
+
+ array<char> data;
+ data.resize(triangles->size() * 3 * sizeof(uchar4));
+
+ uchar4 *data_uchar4 = reinterpret_cast<uchar4 *>(data.data());
+
+ int offset = 0;
+ for (const int3 &tri : *triangles) {
+ Imath::C3f v = (*values)[tri.x];
+ data_uchar4[offset + 0] = color_float_to_byte(make_float3(v.x, v.y, v.z));
+
+ v = (*values)[tri.y];
+ data_uchar4[offset + 1] = color_float_to_byte(make_float3(v.x, v.y, v.z));
+
+ v = (*values)[tri.z];
+ data_uchar4[offset + 2] = color_float_to_byte(make_float3(v.x, v.y, v.z));
+
+ offset += 3;
+ }
+
+ attribute.data.set_time_sampling(*param.getTimeSampling());
+ attribute.data.add_data(data, time);
+ }
+ }
+ }
+ else if (IC4fProperty::matches(prop->getMetaData())) {
+ const IC4fGeomParam &param = IC4fGeomParam(arb_geom_params, prop->getName());
+
+ CachedData::CachedAttribute &attribute = cached_data.add_attribute(attr_name,
+ *param.getTimeSampling());
+
+ for (size_t i = 0; i < param.getNumSamples(); ++i) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ ISampleSelector iss = ISampleSelector(index_t(i));
+
+ IC4fGeomParam::Sample sample;
+ param.getIndexed(sample, iss);
+
+ const chrono_t time = param.getTimeSampling()->getSampleTime(index_t(i));
+
+ C4fArraySamplePtr values = sample.getVals();
+
+ attribute.std = ATTR_STD_NONE;
+
+ if (param.getScope() == kVaryingScope) {
+ attribute.element = ATTR_ELEMENT_CORNER_BYTE;
+ attribute.type_desc = TypeRGBA;
+
+ const array<int3> *triangles = cached_data.triangles.data_for_time_no_check(time);
+
+ if (!triangles) {
+ return;
+ }
+
+ array<char> data;
+ data.resize(triangles->size() * 3 * sizeof(uchar4));
+
+ uchar4 *data_uchar4 = reinterpret_cast<uchar4 *>(data.data());
+
+ int offset = 0;
+ for (const int3 &tri : *triangles) {
+ Imath::C4f v = (*values)[tri.x];
+ data_uchar4[offset + 0] = color_float4_to_uchar4(make_float4(v.r, v.g, v.b, v.a));
+
+ v = (*values)[tri.y];
+ data_uchar4[offset + 1] = color_float4_to_uchar4(make_float4(v.r, v.g, v.b, v.a));
+
+ v = (*values)[tri.z];
+ data_uchar4[offset + 2] = color_float4_to_uchar4(make_float4(v.r, v.g, v.b, v.a));
+
+ offset += 3;
+ }
+
+ attribute.data.set_time_sampling(*param.getTimeSampling());
+ attribute.data.add_data(data, time);
+ }
+ }
+ }
+}
+
+/* Update existing attributes and remove any attribute not in the cached_data, those attributes
+ * were added by Cycles (e.g. face normals) */
+static void update_attributes(AttributeSet &attributes, CachedData &cached_data, double frame_time)
+{
+ set<Attribute *> cached_attributes;
+
+ for (CachedData::CachedAttribute &attribute : cached_data.attributes) {
+ const array<char> *attr_data = attribute.data.data_for_time(frame_time);
+
+ Attribute *attr = nullptr;
+ if (attribute.std != ATTR_STD_NONE) {
+ attr = attributes.add(attribute.std, attribute.name);
+ }
+ else {
+ attr = attributes.add(attribute.name, attribute.type_desc, attribute.element);
+ }
+ assert(attr);
+
+ cached_attributes.insert(attr);
+
+ if (!attr_data) {
+ /* no new data */
+ continue;
+ }
+
+ /* weak way of detecting if the topology has changed
+ * todo: reuse code from device_update patch */
+ if (attr->buffer.size() != attr_data->size()) {
+ attr->buffer.resize(attr_data->size());
+ }
+
+ memcpy(attr->data(), attr_data->data(), attr_data->size());
+ }
+
+ /* remove any attributes not in cached_attributes */
+ list<Attribute>::iterator it;
+ for (it = attributes.attributes.begin(); it != attributes.attributes.end();) {
+ if (cached_attributes.find(&(*it)) == cached_attributes.end()) {
+ attributes.attributes.erase(it++);
+ continue;
+ }
+
+ it++;
+ }
+}
+
+NODE_DEFINE(AlembicProcedural)
+{
+ NodeType *type = NodeType::add("alembic", create);
+
+ SOCKET_STRING(filepath, "Filename", ustring());
+ SOCKET_FLOAT(frame, "Frame", 1.0f);
+ SOCKET_FLOAT(start_frame, "Start Frame", 1.0f);
+ SOCKET_FLOAT(end_frame, "End Frame", 1.0f);
+ SOCKET_FLOAT(frame_rate, "Frame Rate", 24.0f);
+ SOCKET_FLOAT(frame_offset, "Frame Offset", 0.0f);
+ SOCKET_FLOAT(default_radius, "Default Radius", 0.01f);
+ SOCKET_FLOAT(scale, "Scale", 1.0f);
+
+ SOCKET_NODE_ARRAY(objects, "Objects", &AlembicObject::node_type);
+
+ return type;
+}
+
+AlembicProcedural::AlembicProcedural() : Procedural(node_type)
+{
+ objects_loaded = false;
+ scene_ = nullptr;
+}
+
+AlembicProcedural::~AlembicProcedural()
+{
+ ccl::set<Geometry *> geometries_set;
+ ccl::set<Object *> objects_set;
+ ccl::set<AlembicObject *> abc_objects_set;
+
+ foreach (Node *node, objects) {
+ AlembicObject *abc_object = static_cast<AlembicObject *>(node);
+
+ if (abc_object->get_object()) {
+ objects_set.insert(abc_object->get_object());
+
+ if (abc_object->get_object()->get_geometry()) {
+ geometries_set.insert(abc_object->get_object()->get_geometry());
+ }
+ }
+
+ delete_node(abc_object);
+ }
+
+ /* We may delete a Procedural before rendering started, so scene_ can be null. */
+ if (!scene_) {
+ assert(geometries_set.empty());
+ assert(objects_set.empty());
+ return;
+ }
+
+ scene_->delete_nodes(geometries_set, this);
+ scene_->delete_nodes(objects_set, this);
+}
+
+void AlembicProcedural::generate(Scene *scene, Progress &progress)
+{
+ assert(scene_ == nullptr || scene_ == scene);
+ scene_ = scene;
+
+ bool need_shader_updates = false;
+
+ /* Check for changes in shaders (newly requested attributes). */
+ foreach (Node *object_node, objects) {
+ AlembicObject *object = static_cast<AlembicObject *>(object_node);
+
+ foreach (Node *shader_node, object->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(shader_node);
+
+ if (shader->need_update_geometry()) {
+ object->need_shader_update = true;
+ need_shader_updates = true;
+ }
+ }
+ }
+
+ if (!is_modified() && !need_shader_updates) {
+ return;
+ }
+
+ if (!archive.valid()) {
+ Alembic::AbcCoreFactory::IFactory factory;
+ factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);
+ archive = factory.getArchive(filepath.c_str());
+
+ if (!archive.valid()) {
+ /* avoid potential infinite update loops in viewport synchronization */
+ filepath.clear();
+ clear_modified();
+ return;
+ }
+ }
+
+ if (!objects_loaded || objects_is_modified()) {
+ load_objects(progress);
+ objects_loaded = true;
+ }
+
+ const chrono_t frame_time = (chrono_t)((frame - frame_offset) / frame_rate);
+
+ foreach (Node *node, objects) {
+ AlembicObject *object = static_cast<AlembicObject *>(node);
+
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ /* skip constant objects */
+ if (object->has_data_loaded() && object->is_constant() && !object->is_modified() &&
+ !object->need_shader_update && !scale_is_modified()) {
+ continue;
+ }
+
+ if (IPolyMesh::matches(object->iobject.getHeader())) {
+ read_mesh(scene, object, frame_time, progress);
+ }
+ else if (ICurves::matches(object->iobject.getHeader())) {
+ read_curves(scene, object, frame_time, progress);
+ }
+ else if (ISubD::matches(object->iobject.getHeader())) {
+ read_subd(scene, object, frame_time, progress);
+ }
+
+ object->clear_modified();
+ }
+
+ clear_modified();
+}
+
+void AlembicProcedural::add_object(AlembicObject *object)
+{
+ objects.push_back_slow(object);
+ tag_objects_modified();
+}
+
+void AlembicProcedural::tag_update(Scene *scene)
+{
+ scene->procedural_manager->tag_update();
+}
+
+AlembicObject *AlembicProcedural::get_or_create_object(const ustring &path)
+{
+ foreach (Node *node, objects) {
+ AlembicObject *object = static_cast<AlembicObject *>(node);
+
+ if (object->get_path() == path) {
+ return object;
+ }
+ }
+
+ AlembicObject *object = create_node<AlembicObject>();
+ object->set_path(path);
+
+ add_object(object);
+
+ return object;
+}
+
+void AlembicProcedural::load_objects(Progress &progress)
+{
+ unordered_map<string, AlembicObject *> object_map;
+
+ foreach (Node *node, objects) {
+ AlembicObject *object = static_cast<AlembicObject *>(node);
+
+ /* only consider newly added objects */
+ if (object->get_object() == nullptr) {
+ object_map.insert({object->get_path().c_str(), object});
+ }
+ }
+
+ IObject root = archive.getTop();
+
+ for (size_t i = 0; i < root.getNumChildren(); ++i) {
+ walk_hierarchy(root, root.getChildHeader(i), nullptr, object_map, progress);
+ }
+}
+
+void AlembicProcedural::read_mesh(Scene *scene,
+ AlembicObject *abc_object,
+ Abc::chrono_t frame_time,
+ Progress &progress)
+{
+ IPolyMesh polymesh(abc_object->iobject, Alembic::Abc::kWrapExisting);
+
+ Mesh *mesh = nullptr;
+
+ /* create a mesh node in the scene if not already done */
+ if (!abc_object->get_object()) {
+ mesh = scene->create_node<Mesh>();
+ mesh->set_owner(this);
+ mesh->name = abc_object->iobject.getName();
+
+ array<Node *> used_shaders = abc_object->get_used_shaders();
+ mesh->set_used_shaders(used_shaders);
+
+ /* create object*/
+ Object *object = scene->create_node<Object>();
+ object->set_owner(this);
+ object->set_geometry(mesh);
+ object->set_tfm(abc_object->xform);
+ object->name = abc_object->iobject.getName();
+
+ abc_object->set_object(object);
+ }
+ else {
+ mesh = static_cast<Mesh *>(abc_object->get_object()->get_geometry());
+ }
+
+ CachedData &cached_data = abc_object->get_cached_data();
+ IPolyMeshSchema schema = polymesh.getSchema();
+
+ if (!abc_object->has_data_loaded()) {
+ abc_object->load_all_data(this, schema, scale, progress);
+ }
+ else {
+ if (abc_object->need_shader_update) {
+ abc_object->update_shader_attributes(schema.getArbGeomParams(), progress);
+ }
+
+ if (scale_is_modified()) {
+ abc_object->setup_transform_cache(scale);
+ }
+ }
+
+ /* update sockets */
+
+ Object *object = abc_object->get_object();
+ cached_data.transforms.copy_to_socket(frame_time, object, object->get_tfm_socket());
+
+ cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
+
+ cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_shader_socket());
+
+ array<int3> *triangle_data = cached_data.triangles.data_for_time(frame_time);
+ if (triangle_data) {
+ array<int> triangles;
+ array<bool> smooth;
+
+ triangles.reserve(triangle_data->size() * 3);
+ smooth.reserve(triangle_data->size());
+
+ for (size_t i = 0; i < triangle_data->size(); ++i) {
+ int3 tri = (*triangle_data)[i];
+ triangles.push_back_reserved(tri.x);
+ triangles.push_back_reserved(tri.y);
+ triangles.push_back_reserved(tri.z);
+ smooth.push_back_reserved(1);
+ }
+
+ mesh->set_triangles(triangles);
+ mesh->set_smooth(smooth);
+ }
+
+ /* update attributes */
+
+ update_attributes(mesh->attributes, cached_data, frame_time);
+
+ /* we don't yet support arbitrary attributes, for now add vertex
+ * coordinates as generated coordinates if requested */
+ if (mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
+ memcpy(
+ attr->data_float3(), mesh->get_verts().data(), sizeof(float3) * mesh->get_verts().size());
+ }
+
+ if (mesh->is_modified()) {
+ bool need_rebuild = mesh->triangles_is_modified();
+ mesh->tag_update(scene, need_rebuild);
+ }
+}
+
+void AlembicProcedural::read_subd(Scene *scene,
+ AlembicObject *abc_object,
+ Abc::chrono_t frame_time,
+ Progress &progress)
+{
+ ISubD subd_mesh(abc_object->iobject, Alembic::Abc::kWrapExisting);
+ ISubDSchema schema = subd_mesh.getSchema();
+
+ Mesh *mesh = nullptr;
+
+ /* create a mesh node in the scene if not already done */
+ if (!abc_object->get_object()) {
+ mesh = scene->create_node<Mesh>();
+ mesh->set_owner(this);
+ mesh->name = abc_object->iobject.getName();
+
+ array<Node *> used_shaders = abc_object->get_used_shaders();
+ mesh->set_used_shaders(used_shaders);
+
+ /* Alembic is OpenSubDiv compliant, there is no option to set another subdivision type. */
+ mesh->set_subdivision_type(Mesh::SubdivisionType::SUBDIVISION_CATMULL_CLARK);
+
+ /* create object*/
+ Object *object = scene->create_node<Object>();
+ object->set_owner(this);
+ object->set_geometry(mesh);
+ object->set_tfm(abc_object->xform);
+ object->name = abc_object->iobject.getName();
+
+ abc_object->set_object(object);
+ }
+ else {
+ mesh = static_cast<Mesh *>(abc_object->get_object()->get_geometry());
+ }
+
+ if (!abc_object->has_data_loaded()) {
+ abc_object->load_all_data(this, schema, scale, progress);
+ }
+ else {
+ if (abc_object->need_shader_update) {
+ abc_object->update_shader_attributes(schema.getArbGeomParams(), progress);
+ }
+
+ if (scale_is_modified()) {
+ abc_object->setup_transform_cache(scale);
+ }
+ }
+
+ mesh->set_subd_max_level(abc_object->get_subd_max_level());
+ mesh->set_subd_dicing_rate(abc_object->get_subd_dicing_rate());
+
+ CachedData &cached_data = abc_object->get_cached_data();
+
+ if (abc_object->subd_max_level_is_modified() || abc_object->subd_dicing_rate_is_modified()) {
+ /* need to reset the current data is something changed */
+ cached_data.invalidate_last_loaded_time();
+ }
+
+ /* Cycles overwrites the original triangles when computing displacement, so we always have to
+ * repass the data if something is animated (vertices most likely) to avoid buffer overflows. */
+ if (!cached_data.is_constant()) {
+ cached_data.invalidate_last_loaded_time();
+
+ /* remove previous triangles, if any */
+ array<int> triangles;
+ mesh->set_triangles(triangles);
+ }
+
+ mesh->clear_non_sockets();
+
+ /* Update sockets. */
+
+ Object *object = abc_object->get_object();
+ cached_data.transforms.copy_to_socket(frame_time, object, object->get_tfm_socket());
+
+ cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
+
+ /* cached_data.shader is also used for subd_shader */
+ cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_subd_shader_socket());
+
+ cached_data.subd_start_corner.copy_to_socket(
+ frame_time, mesh, mesh->get_subd_start_corner_socket());
+
+ cached_data.subd_num_corners.copy_to_socket(
+ frame_time, mesh, mesh->get_subd_num_corners_socket());
+
+ cached_data.subd_smooth.copy_to_socket(frame_time, mesh, mesh->get_subd_smooth_socket());
+
+ cached_data.subd_ptex_offset.copy_to_socket(
+ frame_time, mesh, mesh->get_subd_ptex_offset_socket());
+
+ cached_data.subd_face_corners.copy_to_socket(
+ frame_time, mesh, mesh->get_subd_face_corners_socket());
+
+ cached_data.num_ngons.copy_to_socket(frame_time, mesh, mesh->get_num_ngons_socket());
+
+ cached_data.subd_creases_edge.copy_to_socket(
+ frame_time, mesh, mesh->get_subd_creases_edge_socket());
+
+ cached_data.subd_creases_weight.copy_to_socket(
+ frame_time, mesh, mesh->get_subd_creases_weight_socket());
+
+ mesh->set_num_subd_faces(mesh->get_subd_shader().size());
+
+ /* Update attributes. */
+
+ update_attributes(mesh->subd_attributes, cached_data, frame_time);
+
+ /* we don't yet support arbitrary attributes, for now add vertex
+ * coordinates as generated coordinates if requested */
+ if (mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
+ memcpy(
+ attr->data_float3(), mesh->get_verts().data(), sizeof(float3) * mesh->get_verts().size());
+ }
+
+ if (mesh->is_modified()) {
+ bool need_rebuild = (mesh->triangles_is_modified()) ||
+ (mesh->subd_num_corners_is_modified()) ||
+ (mesh->subd_shader_is_modified()) || (mesh->subd_smooth_is_modified()) ||
+ (mesh->subd_ptex_offset_is_modified()) ||
+ (mesh->subd_start_corner_is_modified()) ||
+ (mesh->subd_face_corners_is_modified());
+
+ mesh->tag_update(scene, need_rebuild);
+ }
+}
+
+void AlembicProcedural::read_curves(Scene *scene,
+ AlembicObject *abc_object,
+ Abc::chrono_t frame_time,
+ Progress &progress)
+{
+ ICurves curves(abc_object->iobject, Alembic::Abc::kWrapExisting);
+ Hair *hair;
+
+ /* create a hair node in the scene if not already done */
+ if (!abc_object->get_object()) {
+ hair = scene->create_node<Hair>();
+ hair->set_owner(this);
+ hair->name = abc_object->iobject.getName();
+
+ array<Node *> used_shaders = abc_object->get_used_shaders();
+ hair->set_used_shaders(used_shaders);
+
+ /* create object*/
+ Object *object = scene->create_node<Object>();
+ object->set_owner(this);
+ object->set_geometry(hair);
+ object->set_tfm(abc_object->xform);
+ object->name = abc_object->iobject.getName();
+
+ abc_object->set_object(object);
+ }
+ else {
+ hair = static_cast<Hair *>(abc_object->get_object()->get_geometry());
+ }
+
+ ICurvesSchema schema = curves.getSchema();
+
+ if (!abc_object->has_data_loaded() || default_radius_is_modified() ||
+ abc_object->radius_scale_is_modified()) {
+ abc_object->load_all_data(this, schema, scale, progress, default_radius);
+ }
+ else {
+ if (scale_is_modified()) {
+ abc_object->setup_transform_cache(scale);
+ }
+ }
+
+ CachedData &cached_data = abc_object->get_cached_data();
+
+ /* update sockets */
+
+ Object *object = abc_object->get_object();
+ cached_data.transforms.copy_to_socket(frame_time, object, object->get_tfm_socket());
+
+ cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket());
+
+ cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
+
+ cached_data.curve_shader.copy_to_socket(frame_time, hair, hair->get_curve_shader_socket());
+
+ cached_data.curve_first_key.copy_to_socket(frame_time, hair, hair->get_curve_first_key_socket());
+
+ /* update attributes */
+
+ update_attributes(hair->attributes, cached_data, frame_time);
+
+ /* we don't yet support arbitrary attributes, for now add first keys as generated coordinates if
+ * requested */
+ if (hair->need_attribute(scene, ATTR_STD_GENERATED)) {
+ Attribute *attr_generated = hair->attributes.add(ATTR_STD_GENERATED);
+ float3 *generated = attr_generated->data_float3();
+
+ for (size_t i = 0; i < hair->num_curves(); i++) {
+ generated[i] = hair->get_curve_keys()[hair->get_curve(i).first_key];
+ }
+ }
+
+ const bool rebuild = (hair->curve_keys_is_modified() || hair->curve_radius_is_modified());
+ hair->tag_update(scene, rebuild);
+}
+
+void AlembicProcedural::walk_hierarchy(
+ IObject parent,
+ const ObjectHeader &header,
+ MatrixSampleMap *xform_samples,
+ const unordered_map<std::string, AlembicObject *> &object_map,
+ Progress &progress)
+{
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ IObject next_object;
+
+ MatrixSampleMap concatenated_xform_samples;
+
+ if (IXform::matches(header)) {
+ IXform xform(parent, header.getName());
+
+ IXformSchema &xs = xform.getSchema();
+
+ if (xs.getNumOps() > 0) {
+ TimeSamplingPtr ts = xs.getTimeSampling();
+ MatrixSampleMap local_xform_samples;
+
+ MatrixSampleMap *temp_xform_samples = nullptr;
+ if (xform_samples == nullptr) {
+ /* If there is no parent transforms, fill the map directly. */
+ temp_xform_samples = &concatenated_xform_samples;
+ }
+ else {
+ /* use a temporary map */
+ temp_xform_samples = &local_xform_samples;
+ }
+
+ for (size_t i = 0; i < xs.getNumSamples(); ++i) {
+ chrono_t sample_time = ts->getSampleTime(index_t(i));
+ XformSample sample = xs.getValue(ISampleSelector(sample_time));
+ temp_xform_samples->insert({sample_time, sample.getMatrix()});
+ }
+
+ if (xform_samples != nullptr) {
+ concatenate_xform_samples(*xform_samples, local_xform_samples, concatenated_xform_samples);
+ }
+
+ xform_samples = &concatenated_xform_samples;
+ }
+
+ next_object = xform;
+ }
+ else if (ISubD::matches(header)) {
+ ISubD subd(parent, header.getName());
+
+ unordered_map<std::string, AlembicObject *>::const_iterator iter;
+ iter = object_map.find(subd.getFullName());
+
+ if (iter != object_map.end()) {
+ AlembicObject *abc_object = iter->second;
+ abc_object->iobject = subd;
+
+ if (xform_samples) {
+ abc_object->xform_samples = *xform_samples;
+ }
+ }
+
+ next_object = subd;
+ }
+ else if (IPolyMesh::matches(header)) {
+ IPolyMesh mesh(parent, header.getName());
+
+ unordered_map<std::string, AlembicObject *>::const_iterator iter;
+ iter = object_map.find(mesh.getFullName());
+
+ if (iter != object_map.end()) {
+ AlembicObject *abc_object = iter->second;
+ abc_object->iobject = mesh;
+
+ if (xform_samples) {
+ abc_object->xform_samples = *xform_samples;
+ }
+ }
+
+ next_object = mesh;
+ }
+ else if (ICurves::matches(header)) {
+ ICurves curves(parent, header.getName());
+
+ unordered_map<std::string, AlembicObject *>::const_iterator iter;
+ iter = object_map.find(curves.getFullName());
+
+ if (iter != object_map.end()) {
+ AlembicObject *abc_object = iter->second;
+ abc_object->iobject = curves;
+
+ if (xform_samples) {
+ abc_object->xform_samples = *xform_samples;
+ }
+ }
+
+ next_object = curves;
+ }
+ else if (IFaceSet::matches(header)) {
+ // ignore the face set, it will be read along with the data
+ }
+ else {
+ // unsupported type for now (Points, NuPatch)
+ next_object = parent.getChild(header.getName());
+ }
+
+ if (next_object.valid()) {
+ for (size_t i = 0; i < next_object.getNumChildren(); ++i) {
+ walk_hierarchy(
+ next_object, next_object.getChildHeader(i), xform_samples, object_map, progress);
+ }
+ }
+}
+
+CCL_NAMESPACE_END
+
+#endif
diff --git a/intern/cycles/render/alembic.h b/intern/cycles/render/alembic.h
new file mode 100644
index 00000000000..6b0d32fb3ab
--- /dev/null
+++ b/intern/cycles/render/alembic.h
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2011-2018 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "graph/node.h"
+#include "render/attribute.h"
+#include "render/procedural.h"
+#include "util/util_set.h"
+#include "util/util_transform.h"
+#include "util/util_vector.h"
+
+#ifdef WITH_ALEMBIC
+
+# include <Alembic/AbcCoreFactory/All.h>
+# include <Alembic/AbcGeom/All.h>
+
+CCL_NAMESPACE_BEGIN
+
+class AlembicProcedural;
+class Geometry;
+class Object;
+class Progress;
+class Shader;
+
+using MatrixSampleMap = std::map<Alembic::Abc::chrono_t, Alembic::Abc::M44d>;
+
+/* Helpers to detect if some type is a ccl::array. */
+template<typename> struct is_array : public std::false_type {
+};
+
+template<typename T> struct is_array<array<T>> : public std::true_type {
+};
+
+/* Store the data set for an animation at every time points, or at the beginning of the animation
+ * for constant data.
+ *
+ * The data is supposed to be stored in chronological order, and is looked up using the current
+ * animation time in seconds using the TimeSampling from the Alembic property. */
+template<typename T> class DataStore {
+ struct DataTimePair {
+ double time = 0;
+ T data{};
+ };
+
+ vector<DataTimePair> data{};
+ Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
+
+ double last_loaded_time = std::numeric_limits<double>::max();
+
+ public:
+ void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling_)
+ {
+ time_sampling = time_sampling_;
+ }
+
+ Alembic::AbcCoreAbstract::TimeSampling get_time_sampling() const
+ {
+ return time_sampling;
+ }
+
+ /* Get the data for the specified time.
+ * Return nullptr if there is no data or if the data for this time was already loaded. */
+ T *data_for_time(double time)
+ {
+ if (size() == 0) {
+ return nullptr;
+ }
+
+ std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
+ index_pair = time_sampling.getNearIndex(time, data.size());
+ DataTimePair &data_pair = data[index_pair.first];
+
+ if (last_loaded_time == data_pair.time) {
+ return nullptr;
+ }
+
+ last_loaded_time = data_pair.time;
+
+ return &data_pair.data;
+ }
+
+ /* get the data for the specified time, but do not check if the data was already loaded for this
+ * time return nullptr if there is no data */
+ T *data_for_time_no_check(double time)
+ {
+ if (size() == 0) {
+ return nullptr;
+ }
+
+ std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
+ index_pair = time_sampling.getNearIndex(time, data.size());
+ DataTimePair &data_pair = data[index_pair.first];
+ return &data_pair.data;
+ }
+
+ void add_data(T &data_, double time)
+ {
+ if constexpr (is_array<T>::value) {
+ data.emplace_back();
+ data.back().data.steal_data(data_);
+ data.back().time = time;
+ return;
+ }
+
+ data.push_back({time, data_});
+ }
+
+ bool is_constant() const
+ {
+ return data.size() <= 1;
+ }
+
+ size_t size() const
+ {
+ return data.size();
+ }
+
+ void clear()
+ {
+ invalidate_last_loaded_time();
+ data.clear();
+ }
+
+ void invalidate_last_loaded_time()
+ {
+ last_loaded_time = std::numeric_limits<double>::max();
+ }
+
+ /* Copy the data for the specified time to the node's socket. If there is no
+ * data for this time or it was already loaded, do nothing. */
+ void copy_to_socket(double time, Node *node, const SocketType *socket)
+ {
+ T *data_ = data_for_time(time);
+
+ if (data_ == nullptr) {
+ return;
+ }
+
+ /* TODO(kevindietrich): arrays are emptied when passed to the sockets, so for now we copy the
+ * arrays to avoid reloading the data */
+ T value = *data_;
+ node->set(*socket, value);
+ }
+};
+
+/* Actual cache for the stored data.
+ * This caches the topological, transformation, and attribute data for a Mesh node or a Hair node
+ * inside of DataStores.
+ */
+struct CachedData {
+ DataStore<Transform> transforms{};
+
+ /* mesh data */
+ DataStore<array<float3>> vertices;
+ DataStore<array<int3>> triangles{};
+ /* triangle "loops" are the polygons' vertices indices used for indexing face varying attributes
+ * (like UVs) */
+ DataStore<array<int3>> triangles_loops{};
+ DataStore<array<int>> shader{};
+
+ /* subd data */
+ DataStore<array<int>> subd_start_corner;
+ DataStore<array<int>> subd_num_corners;
+ DataStore<array<bool>> subd_smooth;
+ DataStore<array<int>> subd_ptex_offset;
+ DataStore<array<int>> subd_face_corners;
+ DataStore<int> num_ngons;
+ DataStore<array<int>> subd_creases_edge;
+ DataStore<array<float>> subd_creases_weight;
+
+ /* hair data */
+ DataStore<array<float3>> curve_keys;
+ DataStore<array<float>> curve_radius;
+ DataStore<array<int>> curve_first_key;
+ DataStore<array<int>> curve_shader;
+
+ struct CachedAttribute {
+ AttributeStandard std;
+ AttributeElement element;
+ TypeDesc type_desc;
+ ustring name;
+ DataStore<array<char>> data{};
+ };
+
+ vector<CachedAttribute> attributes{};
+
+ void clear();
+
+ CachedAttribute &add_attribute(const ustring &name,
+ const Alembic::Abc::TimeSampling &time_sampling);
+
+ bool is_constant() const;
+
+ void invalidate_last_loaded_time(bool attributes_only = false);
+
+ void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling);
+};
+
+/* Representation of an Alembic object for the AlembicProcedural.
+ *
+ * The AlembicObject holds the path to the Alembic IObject inside of the archive that is desired
+ * for rendering, as well as the list of shaders that it is using.
+ *
+ * The names of the shaders should correspond to the names of the FaceSets inside of the Alembic
+ * archive for per-triangle shader association. If there is no FaceSets, or the names do not
+ * match, the first shader is used for rendering for all triangles.
+ */
+class AlembicObject : public Node {
+ public:
+ NODE_DECLARE
+
+ /* Path to the IObject inside of the archive. */
+ NODE_SOCKET_API(ustring, path)
+
+ /* Shaders used for rendering. */
+ NODE_SOCKET_API_ARRAY(array<Node *>, used_shaders)
+
+ /* Maximum number of subdivisions for ISubD objects. */
+ NODE_SOCKET_API(int, subd_max_level)
+
+ /* Finest level of detail (in pixels) for the subdivision. */
+ NODE_SOCKET_API(float, subd_dicing_rate)
+
+ /* Scale the radius of points and curves. */
+ NODE_SOCKET_API(float, radius_scale)
+
+ AlembicObject();
+ ~AlembicObject();
+
+ private:
+ friend class AlembicProcedural;
+
+ void set_object(Object *object);
+ Object *get_object();
+
+ void load_all_data(AlembicProcedural *proc,
+ Alembic::AbcGeom::IPolyMeshSchema &schema,
+ float scale,
+ Progress &progress);
+ void load_all_data(AlembicProcedural *proc,
+ Alembic::AbcGeom::ISubDSchema &schema,
+ float scale,
+ Progress &progress);
+ void load_all_data(AlembicProcedural *proc,
+ const Alembic::AbcGeom::ICurvesSchema &schema,
+ float scale,
+ Progress &progress,
+ float default_radius);
+
+ bool has_data_loaded() const;
+
+ bool need_shader_update = true;
+
+ MatrixSampleMap xform_samples;
+ Alembic::AbcGeom::IObject iobject;
+ Transform xform;
+
+ CachedData &get_cached_data()
+ {
+ return cached_data;
+ }
+
+ bool is_constant() const
+ {
+ return cached_data.is_constant();
+ }
+
+ Object *object = nullptr;
+
+ bool data_loaded = false;
+
+ CachedData cached_data;
+
+ void update_shader_attributes(const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
+ Progress &progress);
+
+ void read_attribute(const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
+ const ustring &attr_name,
+ Progress &progress);
+
+ template<typename SchemaType>
+ void read_face_sets(SchemaType &schema,
+ array<int> &polygon_to_shader,
+ Alembic::AbcGeom::ISampleSelector sample_sel);
+
+ void setup_transform_cache(float scale);
+
+ AttributeRequestSet get_requested_attributes();
+};
+
+/* Procedural to render objects from a single Alembic archive.
+ *
+ * Every object desired to be rendered should be passed as an AlembicObject through the objects
+ * socket.
+ *
+ * This procedural will load the data set for the entire animation in memory on the first frame,
+ * and directly set the data for the new frames on the created Nodes if needed. This allows for
+ * faster updates between frames as it avoids reseeking the data on disk.
+ */
+class AlembicProcedural : public Procedural {
+ Alembic::AbcGeom::IArchive archive;
+ bool objects_loaded;
+ Scene *scene_;
+
+ public:
+ NODE_DECLARE
+
+ /* The file path to the Alembic archive */
+ NODE_SOCKET_API(ustring, filepath)
+
+ /* The current frame to render. */
+ NODE_SOCKET_API(float, frame)
+
+ /* The first frame to load data for. */
+ NODE_SOCKET_API(float, start_frame)
+
+ /* The last frame to load data for. */
+ NODE_SOCKET_API(float, end_frame)
+
+ /* Subtracted to the current frame. */
+ NODE_SOCKET_API(float, frame_offset)
+
+ /* The frame rate used for rendering in units of frames per second. */
+ NODE_SOCKET_API(float, frame_rate)
+
+ /* List of AlembicObjects to render. */
+ NODE_SOCKET_API_ARRAY(array<Node *>, objects)
+
+ /* Set the default radius to use for curves when the Alembic Curves Schemas do not have radius
+ * information. */
+ NODE_SOCKET_API(float, default_radius)
+
+ /* Multiplier to account for differences in default units for measuring objects in various
+ * software. */
+ NODE_SOCKET_API(float, scale)
+
+ AlembicProcedural();
+ ~AlembicProcedural();
+
+ /* Populates the Cycles scene with Nodes for every contained AlembicObject on the first
+ * invocation, and updates the data on subsequent invocations if the frame changed. */
+ void generate(Scene *scene, Progress &progress);
+
+ /* Add an object to our list of objects, and tag the socket as modified. */
+ void add_object(AlembicObject *object);
+
+ /* Tag for an update only if something was modified. */
+ void tag_update(Scene *scene);
+
+ /* Returns a pointer to an existing or a newly created AlembicObject for the given path. */
+ AlembicObject *get_or_create_object(const ustring &path);
+
+ private:
+ /* Load the data for all the objects whose data has not yet been loaded. */
+ void load_objects(Progress &progress);
+
+ /* Traverse the Alembic hierarchy to lookup the IObjects for the AlembicObjects that were
+ * specified in our objects socket, and accumulate all of the transformations samples along the
+ * way for each IObject. */
+ void walk_hierarchy(Alembic::AbcGeom::IObject parent,
+ const Alembic::AbcGeom::ObjectHeader &ohead,
+ MatrixSampleMap *xform_samples,
+ const unordered_map<string, AlembicObject *> &object_map,
+ Progress &progress);
+
+ /* Read the data for an IPolyMesh at the specified frame_time. Creates corresponding Geometry and
+ * Object Nodes in the Cycles scene if none exist yet. */
+ void read_mesh(Scene *scene,
+ AlembicObject *abc_object,
+ Alembic::AbcGeom::Abc::chrono_t frame_time,
+ Progress &progress);
+
+ /* Read the data for an ICurves at the specified frame_time. Creates corresponding Geometry and
+ * Object Nodes in the Cycles scene if none exist yet. */
+ void read_curves(Scene *scene,
+ AlembicObject *abc_object,
+ Alembic::AbcGeom::Abc::chrono_t frame_time,
+ Progress &progress);
+
+ /* Read the data for an ISubD at the specified frame_time. Creates corresponding Geometry and
+ * Object Nodes in the Cycles scene if none exist yet. */
+ void read_subd(Scene *scene,
+ AlembicObject *abc_object,
+ Alembic::AbcGeom::Abc::chrono_t frame_time,
+ Progress &progress);
+};
+
+CCL_NAMESPACE_END
+
+#endif
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index b478aae9ae2..ce4ae6e4295 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -28,7 +28,7 @@ CCL_NAMESPACE_BEGIN
Attribute::Attribute(
ustring name, TypeDesc type, AttributeElement element, Geometry *geom, AttributePrimitive prim)
- : name(name), std(ATTR_STD_NONE), type(type), element(element), flags(0)
+ : name(name), std(ATTR_STD_NONE), type(type), element(element), flags(0), modified(true)
{
/* string and matrix not supported! */
assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
@@ -82,6 +82,8 @@ void Attribute::add(const float &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
+
+ modified = true;
}
void Attribute::add(const uchar4 &f)
@@ -93,6 +95,8 @@ void Attribute::add(const uchar4 &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
+
+ modified = true;
}
void Attribute::add(const float2 &f)
@@ -104,6 +108,8 @@ void Attribute::add(const float2 &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
+
+ modified = true;
}
void Attribute::add(const float3 &f)
@@ -115,6 +121,8 @@ void Attribute::add(const float3 &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
+
+ modified = true;
}
void Attribute::add(const Transform &f)
@@ -126,6 +134,8 @@ void Attribute::add(const Transform &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
+
+ modified = true;
}
void Attribute::add(const char *data)
@@ -134,6 +144,26 @@ void Attribute::add(const char *data)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
+
+ modified = true;
+}
+
+void Attribute::set_data_from(Attribute &&other)
+{
+ assert(other.std == std);
+ assert(other.type == type);
+ assert(other.element == element);
+
+ this->flags = other.flags;
+
+ if (this->buffer.size() != other.buffer.size()) {
+ this->buffer = std::move(other.buffer);
+ modified = true;
+ }
+ else if (memcmp(this->data(), other.data(), other.buffer.size()) != 0) {
+ this->buffer = std::move(other.buffer);
+ modified = true;
+ }
}
size_t Attribute::data_sizeof() const
@@ -627,6 +657,42 @@ void AttributeSet::clear(bool preserve_voxel_data)
}
}
+void AttributeSet::update(AttributeSet &&new_attributes)
+{
+ /* add or update old_attributes based on the new_attributes */
+ foreach (Attribute &attr, new_attributes.attributes) {
+ Attribute *nattr = add(attr.name, attr.type, attr.element);
+ nattr->std = attr.std;
+ nattr->set_data_from(std::move(attr));
+ }
+
+ /* remove any attributes not on new_attributes */
+ list<Attribute>::iterator it;
+ for (it = attributes.begin(); it != attributes.end();) {
+ if (it->std != ATTR_STD_NONE) {
+ if (new_attributes.find(it->std) == nullptr) {
+ attributes.erase(it++);
+ continue;
+ }
+ }
+ else if (it->name != "") {
+ if (new_attributes.find(it->name) == nullptr) {
+ attributes.erase(it++);
+ continue;
+ }
+ }
+
+ it++;
+ }
+}
+
+void AttributeSet::clear_modified()
+{
+ foreach (Attribute &attr, attributes) {
+ attr.modified = false;
+ }
+}
+
/* AttributeRequest */
AttributeRequest::AttributeRequest(ustring name_)
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index 9990a1325a7..f9997d3c422 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -54,6 +54,8 @@ class Attribute {
AttributeElement element;
uint flags; /* enum AttributeFlag */
+ bool modified;
+
Attribute(ustring name,
TypeDesc type,
AttributeElement element,
@@ -159,6 +161,8 @@ class Attribute {
void add(const Transform &tfm);
void add(const char *data);
+ void set_data_from(Attribute &&other);
+
static bool same_storage(TypeDesc a, TypeDesc b);
static const char *standard_name(AttributeStandard std);
static AttributeStandard name_standard(const char *name);
@@ -194,6 +198,12 @@ class AttributeSet {
void resize(bool reserve_only = false);
void clear(bool preserve_voxel_data = false);
+
+ /* Update the attributes in this AttributeSet with the ones from the new set,
+ * and remove any attribute not found on the new set from this. */
+ void update(AttributeSet &&new_attributes);
+
+ void clear_modified();
};
/* AttributeRequest
diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp
index 7bdcb1578c3..1303f894912 100644
--- a/intern/cycles/render/background.cpp
+++ b/intern/cycles/render/background.cpp
@@ -130,8 +130,9 @@ void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
void Background::tag_update(Scene *scene)
{
- scene->integrator->tag_update(scene);
- tag_modified();
+ if (ao_factor_is_modified() || use_ao_is_modified()) {
+ scene->integrator->tag_update(scene, Integrator::BACKGROUND_AO_MODIFIED);
+ }
}
Shader *Background::get_shader(const Scene *scene)
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index 439ebdedb8e..317a3937cab 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -78,7 +78,7 @@ BakeManager::BakeManager()
type = SHADER_EVAL_BAKE;
pass_filter = 0;
- need_update = true;
+ need_update_ = true;
}
BakeManager::~BakeManager()
@@ -114,9 +114,9 @@ void BakeManager::set(Scene *scene,
/* create device and update scene */
scene->film->tag_modified();
- scene->integrator->tag_update(scene);
+ scene->integrator->tag_update(scene, Integrator::UPDATE_ALL);
- need_update = true;
+ need_update_ = true;
}
void BakeManager::device_update(Device * /*device*/,
@@ -124,7 +124,7 @@ void BakeManager::device_update(Device * /*device*/,
Scene *scene,
Progress & /* progress */)
{
- if (!need_update)
+ if (!need_update())
return;
scoped_callback_timer timer([scene](double time) {
@@ -152,11 +152,21 @@ void BakeManager::device_update(Device * /*device*/,
object_index++;
}
- need_update = false;
+ need_update_ = false;
}
void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
{
}
+void BakeManager::tag_update()
+{
+ need_update_ = true;
+}
+
+bool BakeManager::need_update() const
+{
+ return need_update_;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
index 93e664c2ab1..655b9b1cf7e 100644
--- a/intern/cycles/render/bake.h
+++ b/intern/cycles/render/bake.h
@@ -36,9 +36,12 @@ class BakeManager {
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene);
- bool need_update;
+ void tag_update();
+
+ bool need_update() const;
private:
+ bool need_update_;
ShaderEvalType type;
int pass_filter;
std::string object_name;
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 045931ffdac..0948b20628f 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -448,7 +448,7 @@ bool RenderBuffers::get_pass_rect(
pixels[1] = f.y * scale_exposure;
pixels[2] = f.z * scale_exposure;
- /* clamp since alpha might be > 1.0 due to russian roulette */
+ /* Clamp since alpha might be > 1.0 due to Russian roulette. */
pixels[3] = saturate(f.w * scale);
}
}
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 3beb3d1d4d3..30bf6c4241a 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -252,11 +252,11 @@ void Camera::update(Scene *scene)
Transform fulltoborder = transform_from_viewplane(viewport_camera_border);
Transform bordertofull = transform_inverse(fulltoborder);
- /* ndc to raster */
+ /* NDC to raster. */
Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull;
Transform full_ndctoraster = transform_scale(full_width, full_height, 1.0f) * bordertofull;
- /* raster to screen */
+ /* Raster to screen. */
Transform screentondc = fulltoborder * transform_from_viewplane(viewplane);
Transform screentoraster = ndctoraster * screentondc;
@@ -264,7 +264,7 @@ void Camera::update(Scene *scene)
Transform full_screentoraster = full_ndctoraster * screentondc;
Transform full_rastertoscreen = transform_inverse(full_screentoraster);
- /* screen to camera */
+ /* Screen to camera. */
ProjectionTransform cameratoscreen;
if (camera_type == CAMERA_PERSPECTIVE)
cameratoscreen = projection_perspective(fov, nearclip, farclip);
diff --git a/intern/cycles/render/colorspace.cpp b/intern/cycles/render/colorspace.cpp
index 57979d5f225..4c9e86ea278 100644
--- a/intern/cycles/render/colorspace.cpp
+++ b/intern/cycles/render/colorspace.cpp
@@ -386,7 +386,7 @@ void ColorSpaceManager::free_memory()
#endif
}
-/* Template instanstations so we don't have to inline functions. */
+/* Template instantiations so we don't have to inline functions. */
template void ColorSpaceManager::to_scene_linear(ustring, uchar *, size_t, bool);
template void ColorSpaceManager::to_scene_linear(ustring, ushort *, size_t, bool);
template void ColorSpaceManager::to_scene_linear(ustring, half *, size_t, bool);
diff --git a/intern/cycles/render/denoising.cpp b/intern/cycles/render/denoising.cpp
index 76408ca4849..ddbe7484800 100644
--- a/intern/cycles/render/denoising.cpp
+++ b/intern/cycles/render/denoising.cpp
@@ -847,7 +847,7 @@ bool DenoiseImage::save_output(const string &out_filepath, string &error)
out.reset();
- /* Copy temporary file to outputput filepath. */
+ /* Copy temporary file to output filepath. */
string rename_error;
if (ok && !OIIO::Filesystem::rename(tmp_filepath, out_filepath, rename_error)) {
error = "Failed to move denoised image to " + out_filepath + ": " + rename_error;
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 5c3778f6ae5..9b7657802d6 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -688,16 +688,16 @@ void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *sce
void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes)
{
if (Pass::contains(scene->passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) {
- scene->geometry_manager->tag_update(scene);
+ scene->geometry_manager->tag_update(scene, GeometryManager::UV_PASS_NEEDED);
foreach (Shader *shader, scene->shaders)
- shader->need_update_geometry = true;
+ shader->need_update_uvs = true;
}
else if (Pass::contains(scene->passes, PASS_MOTION) != Pass::contains(passes_, PASS_MOTION)) {
- scene->geometry_manager->tag_update(scene);
+ scene->geometry_manager->tag_update(scene, GeometryManager::MOTION_PASS_NEEDED);
}
else if (Pass::contains(scene->passes, PASS_AO) != Pass::contains(passes_, PASS_AO)) {
- scene->integrator->tag_update(scene);
+ scene->integrator->tag_update(scene, Integrator::AO_PASS_MODIFIED);
}
if (update_passes) {
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index 6fc217f2d76..f79b1689c14 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -240,7 +240,6 @@ void Geometry::compute_bvh(
}
}
- clear_modified();
need_update_rebuild = false;
}
@@ -262,22 +261,21 @@ bool Geometry::has_voxel_attributes() const
void Geometry::tag_update(Scene *scene, bool rebuild)
{
- tag_modified();
-
if (rebuild) {
need_update_rebuild = true;
- scene->light_manager->need_update = true;
+ scene->light_manager->tag_update(scene, LightManager::MESH_NEED_REBUILD);
}
else {
foreach (Node *node, used_shaders) {
Shader *shader = static_cast<Shader *>(node);
- if (shader->has_surface_emission)
- scene->light_manager->need_update = true;
+ if (shader->has_surface_emission) {
+ scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
+ break;
+ }
}
}
- scene->geometry_manager->need_update = true;
- scene->object_manager->need_update = true;
+ scene->geometry_manager->tag_update(scene, GeometryManager::GEOMETRY_MODIFIED);
}
void Geometry::tag_bvh_update(bool rebuild)
@@ -293,7 +291,7 @@ void Geometry::tag_bvh_update(bool rebuild)
GeometryManager::GeometryManager()
{
- need_update = true;
+ update_flags = UPDATE_ALL;
need_flags_update = true;
}
@@ -494,6 +492,10 @@ void GeometryManager::update_svm_attributes(Device *,
if (attr_map_size == 0)
return;
+ if (!dscene->attributes_map.need_realloc()) {
+ return;
+ }
+
/* create attribute map */
uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint));
@@ -602,8 +604,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_uchar4_offset;
assert(attr_uchar4.size() >= offset + size);
- for (size_t k = 0; k < size; k++) {
- attr_uchar4[offset + k] = data[k];
+ if (mattr->modified) {
+ for (size_t k = 0; k < size; k++) {
+ attr_uchar4[offset + k] = data[k];
+ }
}
attr_uchar4_offset += size;
}
@@ -612,8 +616,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_float_offset;
assert(attr_float.size() >= offset + size);
- for (size_t k = 0; k < size; k++) {
- attr_float[offset + k] = data[k];
+ if (mattr->modified) {
+ for (size_t k = 0; k < size; k++) {
+ attr_float[offset + k] = data[k];
+ }
}
attr_float_offset += size;
}
@@ -622,8 +628,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_float2_offset;
assert(attr_float2.size() >= offset + size);
- for (size_t k = 0; k < size; k++) {
- attr_float2[offset + k] = data[k];
+ if (mattr->modified) {
+ for (size_t k = 0; k < size; k++) {
+ attr_float2[offset + k] = data[k];
+ }
}
attr_float2_offset += size;
}
@@ -632,8 +640,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_float3_offset;
assert(attr_float3.size() >= offset + size * 3);
- for (size_t k = 0; k < size * 3; k++) {
- attr_float3[offset + k] = (&tfm->x)[k];
+ if (mattr->modified) {
+ for (size_t k = 0; k < size * 3; k++) {
+ attr_float3[offset + k] = (&tfm->x)[k];
+ }
}
attr_float3_offset += size * 3;
}
@@ -642,8 +652,10 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_float3_offset;
assert(attr_float3.size() >= offset + size);
- for (size_t k = 0; k < size; k++) {
- attr_float3[offset + k] = data[k];
+ if (mattr->modified) {
+ for (size_t k = 0; k < size; k++) {
+ attr_float3[offset + k] = data[k];
+ }
}
attr_float3_offset += size;
}
@@ -808,6 +820,11 @@ void GeometryManager::device_update_attributes(Device *device,
dscene->attributes_float3.alloc(attr_float3_size);
dscene->attributes_uchar4.alloc(attr_uchar4_size);
+ const bool copy_all_data = dscene->attributes_float.need_realloc() ||
+ dscene->attributes_float2.need_realloc() ||
+ dscene->attributes_float3.need_realloc() ||
+ dscene->attributes_uchar4.need_realloc();
+
size_t attr_float_offset = 0;
size_t attr_float2_offset = 0;
size_t attr_float3_offset = 0;
@@ -822,6 +839,12 @@ void GeometryManager::device_update_attributes(Device *device,
* they actually refer to the same mesh attributes, optimize */
foreach (AttributeRequest &req, attributes.requests) {
Attribute *attr = geom->attributes.find(req);
+
+ if (attr) {
+ /* force a copy if we need to reallocate all the data */
+ attr->modified |= copy_all_data;
+ }
+
update_attribute_element_offset(geom,
dscene->attributes_float,
attr_float_offset,
@@ -840,6 +863,11 @@ void GeometryManager::device_update_attributes(Device *device,
Mesh *mesh = static_cast<Mesh *>(geom);
Attribute *subd_attr = mesh->subd_attributes.find(req);
+ if (subd_attr) {
+ /* force a copy if we need to reallocate all the data */
+ subd_attr->modified |= copy_all_data;
+ }
+
update_attribute_element_offset(mesh,
dscene->attributes_float,
attr_float_offset,
@@ -903,18 +931,10 @@ void GeometryManager::device_update_attributes(Device *device,
/* copy to device */
progress.set_status("Updating Mesh", "Copying Attributes to device");
- if (dscene->attributes_float.size()) {
- dscene->attributes_float.copy_to_device();
- }
- if (dscene->attributes_float2.size()) {
- dscene->attributes_float2.copy_to_device();
- }
- if (dscene->attributes_float3.size()) {
- dscene->attributes_float3.copy_to_device();
- }
- if (dscene->attributes_uchar4.size()) {
- dscene->attributes_uchar4.copy_to_device();
- }
+ dscene->attributes_float.copy_to_device();
+ dscene->attributes_float2.copy_to_device();
+ dscene->attributes_float3.copy_to_device();
+ dscene->attributes_uchar4.copy_to_device();
if (progress.get_cancel())
return;
@@ -1066,17 +1086,34 @@ void GeometryManager::device_update_mesh(
uint *tri_patch = dscene->tri_patch.alloc(tri_size);
float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
+ const bool copy_all_data = dscene->tri_shader.need_realloc() ||
+ dscene->tri_vindex.need_realloc() ||
+ dscene->tri_vnormal.need_realloc() ||
+ dscene->tri_patch.need_realloc() ||
+ dscene->tri_patch_uv.need_realloc();
+
foreach (Geometry *geom, scene->geometry) {
if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
- mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
- mesh->pack_normals(&vnormal[mesh->vert_offset]);
- mesh->pack_verts(tri_prim_index,
- &tri_vindex[mesh->prim_offset],
- &tri_patch[mesh->prim_offset],
- &tri_patch_uv[mesh->vert_offset],
- mesh->vert_offset,
- mesh->prim_offset);
+
+ if (mesh->shader_is_modified() || mesh->smooth_is_modified() ||
+ mesh->triangles_is_modified() || copy_all_data) {
+ mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
+ }
+
+ if (mesh->verts_is_modified() || copy_all_data) {
+ mesh->pack_normals(&vnormal[mesh->vert_offset]);
+ }
+
+ if (mesh->triangles_is_modified() || mesh->vert_patch_uv_is_modified() || copy_all_data) {
+ mesh->pack_verts(tri_prim_index,
+ &tri_vindex[mesh->prim_offset],
+ &tri_patch[mesh->prim_offset],
+ &tri_patch_uv[mesh->vert_offset],
+ mesh->vert_offset,
+ mesh->prim_offset);
+ }
+
if (progress.get_cancel())
return;
}
@@ -1085,11 +1122,11 @@ void GeometryManager::device_update_mesh(
/* vertex coordinates */
progress.set_status("Updating Mesh", "Copying Mesh to device");
- dscene->tri_shader.copy_to_device();
- dscene->tri_vnormal.copy_to_device();
- dscene->tri_vindex.copy_to_device();
- dscene->tri_patch.copy_to_device();
- dscene->tri_patch_uv.copy_to_device();
+ dscene->tri_shader.copy_to_device_if_modified();
+ dscene->tri_vnormal.copy_to_device_if_modified();
+ dscene->tri_vindex.copy_to_device_if_modified();
+ dscene->tri_patch.copy_to_device_if_modified();
+ dscene->tri_patch_uv.copy_to_device_if_modified();
}
if (curve_size != 0) {
@@ -1098,9 +1135,21 @@ void GeometryManager::device_update_mesh(
float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
float4 *curves = dscene->curves.alloc(curve_size);
+ const bool copy_all_data = dscene->curve_keys.need_realloc() || dscene->curves.need_realloc();
+
foreach (Geometry *geom, scene->geometry) {
if (geom->is_hair()) {
Hair *hair = static_cast<Hair *>(geom);
+
+ bool curve_keys_co_modified = hair->curve_radius_is_modified() ||
+ hair->curve_keys_is_modified();
+ bool curve_data_modified = hair->curve_shader_is_modified() ||
+ hair->curve_first_key_is_modified();
+
+ if (!curve_keys_co_modified && !curve_data_modified && !copy_all_data) {
+ continue;
+ }
+
hair->pack_curves(scene,
&curve_keys[hair->curvekey_offset],
&curves[hair->prim_offset],
@@ -1110,11 +1159,11 @@ void GeometryManager::device_update_mesh(
}
}
- dscene->curve_keys.copy_to_device();
- dscene->curves.copy_to_device();
+ dscene->curve_keys.copy_to_device_if_modified();
+ dscene->curves.copy_to_device_if_modified();
}
- if (patch_size != 0) {
+ if (patch_size != 0 && dscene->patches.need_realloc()) {
progress.set_status("Updating Mesh", "Copying Patches to device");
uint *patch_data = dscene->patches.alloc(patch_size);
@@ -1180,16 +1229,25 @@ void GeometryManager::device_update_bvh(Device *device,
VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
- delete scene->bvh;
- BVH *bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
- device->build_bvh(bvh, progress, false);
+ const bool can_refit = scene->bvh != nullptr &&
+ (bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX);
+ const bool pack_all = scene->bvh == nullptr;
+
+ BVH *bvh = scene->bvh;
+ if (!scene->bvh) {
+ bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
+ }
+
+ device->build_bvh(bvh, progress, can_refit);
if (progress.get_cancel()) {
return;
}
+ const bool has_bvh2_layout = (bparams.bvh_layout == BVH_LAYOUT_BVH2);
+
PackedBVH pack;
- if (bparams.bvh_layout == BVH_LAYOUT_BVH2) {
+ if (has_bvh2_layout) {
pack = std::move(static_cast<BVH2 *>(bvh)->pack);
}
else {
@@ -1210,12 +1268,22 @@ void GeometryManager::device_update_bvh(Device *device,
}
pack.root_index = -1;
- pack.prim_tri_index.reserve(num_prims);
- pack.prim_tri_verts.reserve(num_tri_verts);
- pack.prim_type.reserve(num_prims);
- pack.prim_index.reserve(num_prims);
- pack.prim_object.reserve(num_prims);
- pack.prim_visibility.reserve(num_prims);
+
+ if (!pack_all) {
+ /* if we do not need to recreate the BVH, then only the vertices are updated, so we can
+ * safely retake the memory */
+ dscene->prim_tri_verts.give_data(pack.prim_tri_verts);
+ }
+ else {
+ /* It is not strictly necessary to skip those resizes we if do not have to repack, as the OS
+ * will not allocate pages if we do not touch them, however it does help catching bugs. */
+ pack.prim_tri_index.resize(num_prims);
+ pack.prim_tri_verts.resize(num_tri_verts);
+ pack.prim_type.resize(num_prims);
+ pack.prim_index.resize(num_prims);
+ pack.prim_object.resize(num_prims);
+ pack.prim_visibility.resize(num_prims);
+ }
// Merge visibility flags of all objects and find object index for non-instanced geometry
unordered_map<const Geometry *, pair<int, uint>> geometry_to_object_info;
@@ -1229,17 +1297,27 @@ void GeometryManager::device_update_bvh(Device *device,
}
}
+ TaskPool pool;
// Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated
// based on that list, which may be ordered differently from the object list.
foreach (Geometry *geom, scene->geometry) {
+ if (!pack_all && !geom->is_modified()) {
+ continue;
+ }
+
const pair<int, uint> &info = geometry_to_object_info[geom];
- geom->pack_primitives(pack, info.first, info.second);
+ pool.push(function_bind(
+ &Geometry::pack_primitives, geom, &pack, info.first, info.second, pack_all));
}
+ pool.wait_work();
}
/* copy to device */
progress.set_status("Updating Scene BVH", "Copying BVH to device");
+ /* When using BVH2, we always have to copy/update the data as its layout is dependent on the
+ * BVH's leaf nodes which may be different when the objects or vertices move. */
+
if (pack.nodes.size()) {
dscene->bvh_nodes.steal_data(pack.nodes);
dscene->bvh_nodes.copy_to_device();
@@ -1252,7 +1330,7 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->object_node.steal_data(pack.object_node);
dscene->object_node.copy_to_device();
}
- if (pack.prim_tri_index.size()) {
+ if (pack.prim_tri_index.size() && (dscene->prim_tri_index.need_realloc() || has_bvh2_layout)) {
dscene->prim_tri_index.steal_data(pack.prim_tri_index);
dscene->prim_tri_index.copy_to_device();
}
@@ -1260,23 +1338,23 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
dscene->prim_tri_verts.copy_to_device();
}
- if (pack.prim_type.size()) {
+ if (pack.prim_type.size() && (dscene->prim_type.need_realloc() || has_bvh2_layout)) {
dscene->prim_type.steal_data(pack.prim_type);
dscene->prim_type.copy_to_device();
}
- if (pack.prim_visibility.size()) {
+ if (pack.prim_visibility.size() && (dscene->prim_visibility.need_realloc() || has_bvh2_layout)) {
dscene->prim_visibility.steal_data(pack.prim_visibility);
dscene->prim_visibility.copy_to_device();
}
- if (pack.prim_index.size()) {
+ if (pack.prim_index.size() && (dscene->prim_index.need_realloc() || has_bvh2_layout)) {
dscene->prim_index.steal_data(pack.prim_index);
dscene->prim_index.copy_to_device();
}
- if (pack.prim_object.size()) {
+ if (pack.prim_object.size() && (dscene->prim_object.need_realloc() || has_bvh2_layout)) {
dscene->prim_object.steal_data(pack.prim_object);
dscene->prim_object.copy_to_device();
}
- if (pack.prim_time.size()) {
+ if (pack.prim_time.size() && (dscene->prim_time.need_realloc() || has_bvh2_layout)) {
dscene->prim_time.steal_data(pack.prim_time);
dscene->prim_time.copy_to_device();
}
@@ -1289,12 +1367,65 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->data.bvh.scene = NULL;
}
+/* Set of flags used to help determining what data has been modified or needs reallocation, so we
+ * can decide which device data to free or update. */
+enum {
+ DEVICE_CURVE_DATA_MODIFIED = (1 << 0),
+ DEVICE_MESH_DATA_MODIFIED = (1 << 1),
+
+ ATTR_FLOAT_MODIFIED = (1 << 2),
+ ATTR_FLOAT2_MODIFIED = (1 << 3),
+ ATTR_FLOAT3_MODIFIED = (1 << 4),
+ ATTR_UCHAR4_MODIFIED = (1 << 5),
+
+ CURVE_DATA_NEED_REALLOC = (1 << 6),
+ MESH_DATA_NEED_REALLOC = (1 << 7),
+
+ ATTR_FLOAT_NEEDS_REALLOC = (1 << 8),
+ ATTR_FLOAT2_NEEDS_REALLOC = (1 << 9),
+ ATTR_FLOAT3_NEEDS_REALLOC = (1 << 10),
+ ATTR_UCHAR4_NEEDS_REALLOC = (1 << 11),
+
+ ATTRS_NEED_REALLOC = (ATTR_FLOAT_NEEDS_REALLOC | ATTR_FLOAT2_NEEDS_REALLOC |
+ ATTR_FLOAT3_NEEDS_REALLOC | ATTR_UCHAR4_NEEDS_REALLOC),
+ DEVICE_MESH_DATA_NEEDS_REALLOC = (MESH_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC),
+ DEVICE_CURVE_DATA_NEEDS_REALLOC = (CURVE_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC),
+};
+
+static void update_device_flags_attribute(uint32_t &device_update_flags,
+ const AttributeSet &attributes)
+{
+ foreach (const Attribute &attr, attributes.attributes) {
+ if (!attr.modified) {
+ continue;
+ }
+
+ if (attr.element == ATTR_ELEMENT_CORNER) {
+ device_update_flags |= ATTR_UCHAR4_MODIFIED;
+ }
+ else if (attr.type == TypeDesc::TypeFloat) {
+ device_update_flags |= ATTR_FLOAT_MODIFIED;
+ }
+ else if (attr.type == TypeFloat2) {
+ device_update_flags |= ATTR_FLOAT2_MODIFIED;
+ }
+ else if (attr.type == TypeDesc::TypeMatrix) {
+ device_update_flags |= ATTR_FLOAT3_MODIFIED;
+ }
+ else if (attr.element != ATTR_ELEMENT_VOXEL) {
+ device_update_flags |= ATTR_FLOAT3_MODIFIED;
+ }
+ }
+}
+
void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
{
- if (!need_update && !need_flags_update) {
+ if (!need_update() && !need_flags_update) {
return;
}
+ uint32_t device_update_flags = 0;
+
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->geometry.times.add_entry({"device_update_preprocess", time});
@@ -1314,9 +1445,54 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
if (shader->has_volume) {
geom->has_volume = true;
}
+
if (shader->has_surface_bssrdf) {
geom->has_surface_bssrdf = true;
}
+
+ if (shader->need_update_uvs) {
+ device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
+
+ /* Attributes might need to be tessellated if added. */
+ if (geom->is_mesh()) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ if (mesh->need_tesselation()) {
+ mesh->tag_modified();
+ }
+ }
+ }
+
+ if (shader->need_update_attribute) {
+ device_update_flags |= ATTRS_NEED_REALLOC;
+
+ /* Attributes might need to be tessellated if added. */
+ if (geom->is_mesh()) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ if (mesh->need_tesselation()) {
+ mesh->tag_modified();
+ }
+ }
+ }
+
+ if (shader->need_update_displacement) {
+ /* tag displacement related sockets as modified */
+ if (geom->is_mesh()) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ mesh->tag_verts_modified();
+ mesh->tag_subd_dicing_rate_modified();
+ mesh->tag_subd_max_level_modified();
+ mesh->tag_subd_objecttoworld_modified();
+
+ device_update_flags |= ATTRS_NEED_REALLOC;
+ }
+ }
+ }
+
+ /* only check for modified attributes if we do not need to reallocate them already */
+ if ((device_update_flags & ATTRS_NEED_REALLOC) == 0) {
+ update_device_flags_attribute(device_update_flags, geom->attributes);
+ /* don't check for subd_attributes, as if they were modified, we would need to reallocate
+ * anyway */
}
/* Re-create volume mesh if we will rebuild or refit the BVH. Note we
@@ -1332,13 +1508,119 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
Volume *volume = static_cast<Volume *>(geom);
create_volume_mesh(volume, progress);
+
+ /* always reallocate when we have a volume, as we need to rebuild the BVH */
+ device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
}
if (geom->is_hair()) {
/* Set curve shape, still a global scene setting for now. */
Hair *hair = static_cast<Hair *>(geom);
hair->curve_shape = scene->params.hair_shape;
+
+ if (hair->need_update_rebuild) {
+ device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
+ }
+ else if (hair->is_modified()) {
+ device_update_flags |= DEVICE_CURVE_DATA_MODIFIED;
+ }
}
+
+ if (geom->is_mesh()) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+
+ if (mesh->need_update_rebuild) {
+ device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
+ }
+ else if (mesh->is_modified()) {
+ device_update_flags |= DEVICE_MESH_DATA_MODIFIED;
+ }
+ }
+ }
+
+ if (update_flags & (MESH_ADDED | MESH_REMOVED)) {
+ device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
+ }
+
+ if (update_flags & (HAIR_ADDED | HAIR_REMOVED)) {
+ device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
+ }
+
+ /* tag the device arrays for reallocation or modification */
+ DeviceScene *dscene = &scene->dscene;
+
+ if (device_update_flags & (DEVICE_MESH_DATA_NEEDS_REALLOC | DEVICE_CURVE_DATA_NEEDS_REALLOC)) {
+ delete scene->bvh;
+ scene->bvh = nullptr;
+
+ dscene->bvh_nodes.tag_realloc();
+ dscene->bvh_leaf_nodes.tag_realloc();
+ dscene->object_node.tag_realloc();
+ dscene->prim_tri_verts.tag_realloc();
+ dscene->prim_tri_index.tag_realloc();
+ dscene->prim_type.tag_realloc();
+ dscene->prim_visibility.tag_realloc();
+ dscene->prim_index.tag_realloc();
+ dscene->prim_object.tag_realloc();
+ dscene->prim_time.tag_realloc();
+
+ if (device_update_flags & DEVICE_MESH_DATA_NEEDS_REALLOC) {
+ dscene->tri_vnormal.tag_realloc();
+ dscene->tri_vindex.tag_realloc();
+ dscene->tri_patch.tag_realloc();
+ dscene->tri_vnormal.tag_realloc();
+ dscene->tri_patch_uv.tag_realloc();
+ dscene->patches.tag_realloc();
+ }
+
+ if (device_update_flags & DEVICE_CURVE_DATA_NEEDS_REALLOC) {
+ dscene->curves.tag_realloc();
+ dscene->curve_keys.tag_realloc();
+ }
+ }
+
+ if (device_update_flags & ATTR_FLOAT_NEEDS_REALLOC) {
+ dscene->attributes_map.tag_realloc();
+ dscene->attributes_float.tag_realloc();
+ }
+ else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
+ dscene->attributes_float.tag_modified();
+ }
+
+ if (device_update_flags & ATTR_FLOAT2_NEEDS_REALLOC) {
+ dscene->attributes_map.tag_realloc();
+ dscene->attributes_float2.tag_realloc();
+ }
+ else if (device_update_flags & ATTR_FLOAT2_MODIFIED) {
+ dscene->attributes_float2.tag_modified();
+ }
+
+ if (device_update_flags & ATTR_FLOAT3_NEEDS_REALLOC) {
+ dscene->attributes_map.tag_realloc();
+ dscene->attributes_float3.tag_realloc();
+ }
+ else if (device_update_flags & ATTR_FLOAT3_MODIFIED) {
+ dscene->attributes_float3.tag_modified();
+ }
+
+ if (device_update_flags & ATTR_UCHAR4_NEEDS_REALLOC) {
+ dscene->attributes_map.tag_realloc();
+ dscene->attributes_uchar4.tag_realloc();
+ }
+ else if (device_update_flags & ATTR_UCHAR4_MODIFIED) {
+ dscene->attributes_uchar4.tag_modified();
+ }
+
+ if (device_update_flags & DEVICE_MESH_DATA_MODIFIED) {
+ /* if anything else than vertices or shaders are modified, we would need to reallocate, so
+ * these are the only arrays that can be updated */
+ dscene->tri_vnormal.tag_modified();
+ dscene->tri_shader.tag_modified();
+ }
+
+ if (device_update_flags & DEVICE_CURVE_DATA_MODIFIED) {
+ dscene->curve_keys.tag_modified();
+ dscene->curves.tag_modified();
}
need_flags_update = false;
@@ -1423,7 +1705,7 @@ void GeometryManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
- if (!need_update)
+ if (!need_update())
return;
VLOG(1) << "Total " << scene->geometry.size() << " meshes.";
@@ -1439,12 +1721,6 @@ void GeometryManager::device_update(Device *device,
});
foreach (Geometry *geom, scene->geometry) {
- foreach (Node *node, geom->get_used_shaders()) {
- Shader *shader = static_cast<Shader *>(node);
- if (shader->need_update_geometry)
- geom->tag_modified();
- }
-
if (geom->is_modified() &&
(geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME)) {
Mesh *mesh = static_cast<Mesh *>(geom);
@@ -1541,7 +1817,7 @@ void GeometryManager::device_update(Device *device,
}
/* Device update. */
- device_free(device, dscene);
+ device_free(device, dscene, false);
const BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
device->get_bvh_layout_mask());
@@ -1614,7 +1890,7 @@ void GeometryManager::device_update(Device *device,
{"device_update (displacement: attributes)", time});
}
});
- device_free(device, dscene);
+ device_free(device, dscene, false);
device_update_attributes(device, dscene, scene, progress);
if (progress.get_cancel()) {
@@ -1622,6 +1898,9 @@ void GeometryManager::device_update(Device *device,
}
}
+ /* update the bvh even when there is no geometry so the kernel bvh data is still valid,
+ * especially when removing all of the objects during interactive renders */
+ bool need_update_scene_bvh = (scene->bvh == nullptr);
{
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
@@ -1633,6 +1912,7 @@ void GeometryManager::device_update(Device *device,
size_t i = 0;
foreach (Geometry *geom, scene->geometry) {
if (geom->is_modified()) {
+ need_update_scene_bvh = true;
pool.push(function_bind(
&Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh));
if (geom->need_build_bvh(bvh_layout)) {
@@ -1647,7 +1927,9 @@ void GeometryManager::device_update(Device *device,
}
foreach (Shader *shader, scene->shaders) {
- shader->need_update_geometry = false;
+ shader->need_update_uvs = false;
+ shader->need_update_attribute = false;
+ shader->need_update_displacement = false;
}
Scene::MotionType need_motion = scene->need_motion();
@@ -1670,7 +1952,7 @@ void GeometryManager::device_update(Device *device,
return;
}
- {
+ if (need_update_scene_bvh) {
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
@@ -1695,8 +1977,6 @@ void GeometryManager::device_update(Device *device,
}
}
- need_update = false;
-
if (true_displacement_used) {
/* Re-tag flags for update, so they're re-evaluated
* for meshes with correct bounding boxes.
@@ -1706,33 +1986,71 @@ void GeometryManager::device_update(Device *device,
*/
scene->object_manager->need_flags_update = old_need_object_flags_update;
}
+
+ /* unset flags */
+
+ foreach (Geometry *geom, scene->geometry) {
+ geom->clear_modified();
+ geom->attributes.clear_modified();
+
+ if (geom->is_mesh()) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ mesh->subd_attributes.clear_modified();
+ }
+ }
+
+ update_flags = UPDATE_NONE;
+
+ dscene->bvh_nodes.clear_modified();
+ dscene->bvh_leaf_nodes.clear_modified();
+ dscene->object_node.clear_modified();
+ dscene->prim_tri_verts.clear_modified();
+ dscene->prim_tri_index.clear_modified();
+ dscene->prim_type.clear_modified();
+ dscene->prim_visibility.clear_modified();
+ dscene->prim_index.clear_modified();
+ dscene->prim_object.clear_modified();
+ dscene->prim_time.clear_modified();
+ dscene->tri_shader.clear_modified();
+ dscene->tri_vindex.clear_modified();
+ dscene->tri_patch.clear_modified();
+ dscene->tri_vnormal.clear_modified();
+ dscene->tri_patch_uv.clear_modified();
+ dscene->curves.clear_modified();
+ dscene->curve_keys.clear_modified();
+ dscene->patches.clear_modified();
+ dscene->attributes_map.clear_modified();
+ dscene->attributes_float.clear_modified();
+ dscene->attributes_float2.clear_modified();
+ dscene->attributes_float3.clear_modified();
+ dscene->attributes_uchar4.clear_modified();
}
-void GeometryManager::device_free(Device *device, DeviceScene *dscene)
+void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool force_free)
{
- dscene->bvh_nodes.free();
- dscene->bvh_leaf_nodes.free();
- dscene->object_node.free();
- dscene->prim_tri_verts.free();
- dscene->prim_tri_index.free();
- dscene->prim_type.free();
- dscene->prim_visibility.free();
- dscene->prim_index.free();
- dscene->prim_object.free();
- dscene->prim_time.free();
- dscene->tri_shader.free();
- dscene->tri_vnormal.free();
- dscene->tri_vindex.free();
- dscene->tri_patch.free();
- dscene->tri_patch_uv.free();
- dscene->curves.free();
- dscene->curve_keys.free();
- dscene->patches.free();
- dscene->attributes_map.free();
- dscene->attributes_float.free();
- dscene->attributes_float2.free();
- dscene->attributes_float3.free();
- dscene->attributes_uchar4.free();
+ dscene->bvh_nodes.free_if_need_realloc(force_free);
+ dscene->bvh_leaf_nodes.free_if_need_realloc(force_free);
+ dscene->object_node.free_if_need_realloc(force_free);
+ dscene->prim_tri_verts.free_if_need_realloc(force_free);
+ dscene->prim_tri_index.free_if_need_realloc(force_free);
+ dscene->prim_type.free_if_need_realloc(force_free);
+ dscene->prim_visibility.free_if_need_realloc(force_free);
+ dscene->prim_index.free_if_need_realloc(force_free);
+ dscene->prim_object.free_if_need_realloc(force_free);
+ dscene->prim_time.free_if_need_realloc(force_free);
+ dscene->tri_shader.free_if_need_realloc(force_free);
+ dscene->tri_vnormal.free_if_need_realloc(force_free);
+ dscene->tri_vindex.free_if_need_realloc(force_free);
+ dscene->tri_patch.free_if_need_realloc(force_free);
+ dscene->tri_patch_uv.free_if_need_realloc(force_free);
+ dscene->curves.free_if_need_realloc(force_free);
+ dscene->curve_keys.free_if_need_realloc(force_free);
+ dscene->patches.free_if_need_realloc(force_free);
+ dscene->attributes_map.free_if_need_realloc(force_free);
+ dscene->attributes_float.free_if_need_realloc(force_free);
+ dscene->attributes_float2.free_if_need_realloc(force_free);
+ dscene->attributes_float3.free_if_need_realloc(force_free);
+ dscene->attributes_uchar4.free_if_need_realloc(force_free);
/* Signal for shaders like displacement not to do ray tracing. */
dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
@@ -1750,10 +2068,19 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene)
#endif
}
-void GeometryManager::tag_update(Scene *scene)
+void GeometryManager::tag_update(Scene *scene, uint32_t flag)
+{
+ update_flags |= flag;
+
+ /* do not tag the object manager for an update if it is the one who tagged us */
+ if ((flag & OBJECT_MANAGER) == 0) {
+ scene->object_manager->tag_update(scene, ObjectManager::GEOMETRY_MANAGER);
+ }
+}
+
+bool GeometryManager::need_update() const
{
- need_update = true;
- scene->object_manager->need_update = true;
+ return update_flags != UPDATE_NONE;
}
void GeometryManager::collect_statistics(const Scene *scene, RenderStats *stats)
diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h
index b124e950ad2..88388f31a9b 100644
--- a/intern/cycles/render/geometry.h
+++ b/intern/cycles/render/geometry.h
@@ -125,7 +125,7 @@ class Geometry : public Node {
int n,
int total);
- virtual void pack_primitives(PackedBVH &pack, int object, uint visibility) = 0;
+ virtual void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) = 0;
/* Check whether the geometry should have own BVH built separately. Briefly,
* own BVH is needed for geometry, if:
@@ -155,6 +155,11 @@ class Geometry : public Node {
return geometry_type == HAIR;
}
+ bool is_volume() const
+ {
+ return geometry_type == VOLUME;
+ }
+
/* Updates */
void tag_update(Scene *scene, bool rebuild);
@@ -164,9 +169,32 @@ class Geometry : public Node {
/* Geometry Manager */
class GeometryManager {
+ uint32_t update_flags;
+
public:
+ enum : uint32_t {
+ UV_PASS_NEEDED = (1 << 0),
+ MOTION_PASS_NEEDED = (1 << 1),
+ GEOMETRY_MODIFIED = (1 << 2),
+ OBJECT_MANAGER = (1 << 3),
+ MESH_ADDED = (1 << 4),
+ MESH_REMOVED = (1 << 5),
+ HAIR_ADDED = (1 << 6),
+ HAIR_REMOVED = (1 << 7),
+
+ SHADER_ATTRIBUTE_MODIFIED = (1 << 8),
+ SHADER_DISPLACEMENT_MODIFIED = (1 << 9),
+
+ GEOMETRY_ADDED = MESH_ADDED | HAIR_ADDED,
+ GEOMETRY_REMOVED = MESH_REMOVED | HAIR_REMOVED,
+
+ /* tag everything in the manager for an update */
+ UPDATE_ALL = ~0u,
+
+ UPDATE_NONE = 0u,
+ };
+
/* Update Flags */
- bool need_update;
bool need_flags_update;
/* Constructor/Destructor */
@@ -176,10 +204,12 @@ class GeometryManager {
/* Device Updates */
void device_update_preprocess(Device *device, Scene *scene, Progress &progress);
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_free(Device *device, DeviceScene *dscene, bool force_free);
/* Updates */
- void tag_update(Scene *scene);
+ void tag_update(Scene *scene, uint32_t flag);
+
+ bool need_update() const;
/* Statistics */
void collect_statistics(const Scene *scene, RenderStats *stats);
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 4adfebf80ae..5e068e74ce0 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -276,7 +276,7 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
emission->set_color(make_float3(1.0f, 1.0f, 1.0f));
emission->set_strength(1.0f);
convert = add(emission);
- /* Connect float inputs to Strength to save an additional Falue->Color conversion. */
+ /* Connect float inputs to Strength to save an additional Value->Color conversion. */
if (from->type() == SocketType::FLOAT) {
convert_in = convert->input("Strength");
}
diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp
index 896e798b6f9..e94cad6b32e 100644
--- a/intern/cycles/render/hair.cpp
+++ b/intern/cycles/render/hair.cpp
@@ -494,33 +494,38 @@ void Hair::pack_curves(Scene *scene,
}
}
-void Hair::pack_primitives(PackedBVH &pack, int object, uint visibility)
+void Hair::pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all)
{
if (curve_first_key.empty())
return;
- const size_t num_prims = num_segments();
- pack.prim_tri_index.reserve(pack.prim_tri_index.size() + num_prims);
- pack.prim_type.reserve(pack.prim_type.size() + num_prims);
- pack.prim_visibility.reserve(pack.prim_visibility.size() + num_prims);
- pack.prim_index.reserve(pack.prim_index.size() + num_prims);
- pack.prim_object.reserve(pack.prim_object.size() + num_prims);
- // 'pack.prim_time' is unused by Embree and OptiX
+ /* If the BVH does not have to be recreated, we can bail out. */
+ if (!pack_all) {
+ return;
+ }
+
+ unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
+ int *prim_type = &pack->prim_type[optix_prim_offset];
+ unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
+ int *prim_index = &pack->prim_index[optix_prim_offset];
+ int *prim_object = &pack->prim_object[optix_prim_offset];
+ // 'pack->prim_time' is unused by Embree and OptiX
uint type = has_motion_blur() ?
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
PRIMITIVE_MOTION_CURVE_THICK) :
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK);
+ size_t index = 0;
for (size_t j = 0; j < num_curves(); ++j) {
Curve curve = get_curve(j);
- for (size_t k = 0; k < curve.num_segments(); ++k) {
- pack.prim_tri_index.push_back_reserved(-1);
- pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k));
- pack.prim_visibility.push_back_reserved(visibility);
+ for (size_t k = 0; k < curve.num_segments(); ++k, ++index) {
+ prim_tri_index[index] = -1;
+ prim_type[index] = PRIMITIVE_PACK_SEGMENT(type, k);
+ prim_visibility[index] = visibility;
// Each curve segment points back to its curve index
- pack.prim_index.push_back_reserved(j + prim_offset);
- pack.prim_object.push_back_reserved(object);
+ prim_index[index] = j + prim_offset;
+ prim_object[index] = object;
}
}
}
diff --git a/intern/cycles/render/hair.h b/intern/cycles/render/hair.h
index c7be08d679c..4b949f984e5 100644
--- a/intern/cycles/render/hair.h
+++ b/intern/cycles/render/hair.h
@@ -146,7 +146,7 @@ class Hair : public Geometry {
/* BVH */
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
- void pack_primitives(PackedBVH &pack, int object, uint visibility) override;
+ void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) override;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 30858c4f68b..29a95beaf7e 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -298,7 +298,7 @@ bool ImageLoader::is_vdb_loader() const
ImageManager::ImageManager(const DeviceInfo &info)
{
- need_update = true;
+ need_update_ = true;
osl_texture_system = NULL;
animation_frame = 0;
@@ -419,7 +419,7 @@ int ImageManager::add_image_slot(ImageLoader *loader,
thread_scoped_lock device_lock(images_mutex);
- /* Fnd existing image. */
+ /* Find existing image. */
for (slot = 0; slot < images.size(); slot++) {
img = images[slot];
if (img && ImageLoader::equals(img->loader, loader) && img->params == params) {
@@ -451,7 +451,7 @@ int ImageManager::add_image_slot(ImageLoader *loader,
images[slot] = img;
- need_update = true;
+ need_update_ = true;
return slot;
}
@@ -478,7 +478,7 @@ void ImageManager::remove_image_user(int slot)
* the reasons for this is that on shader changes we add and remove nodes
* that use them, but we do not want to reload the image all the time. */
if (image->users == 0)
- need_update = true;
+ need_update_ = true;
}
static bool image_associate_alpha(ImageManager::Image *img)
@@ -810,7 +810,7 @@ void ImageManager::device_free_image(Device *, int slot)
void ImageManager::device_update(Device *device, Scene *scene, Progress &progress)
{
- if (!need_update) {
+ if (!need_update()) {
return;
}
@@ -834,7 +834,7 @@ void ImageManager::device_update(Device *device, Scene *scene, Progress &progres
pool.wait_work();
- need_update = false;
+ need_update_ = false;
}
void ImageManager::device_update_slot(Device *device, Scene *scene, int slot, Progress *progress)
@@ -854,7 +854,7 @@ void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &p
{
/* Load only builtin images, Blender needs this to load evaluated
* scene data from depsgraph before it is freed. */
- if (!need_update) {
+ if (!need_update()) {
return;
}
@@ -896,4 +896,14 @@ void ImageManager::collect_statistics(RenderStats *stats)
}
}
+void ImageManager::tag_update()
+{
+ need_update_ = true;
+}
+
+bool ImageManager::need_update() const
+{
+ return need_update_;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 6ac1db9ed63..c802521db56 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -189,7 +189,9 @@ class ImageManager {
void collect_statistics(RenderStats *stats);
- bool need_update;
+ void tag_update();
+
+ bool need_update() const;
struct Image {
ImageParams params;
@@ -209,6 +211,7 @@ class ImageManager {
};
private:
+ bool need_update_;
bool has_half_images;
thread_mutex device_mutex;
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index e5b9e6bfabf..d93856ceb61 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -17,9 +17,11 @@
#include "render/integrator.h"
#include "device/device.h"
#include "render/background.h"
+#include "render/camera.h"
#include "render/film.h"
#include "render/jitter.h"
#include "render/light.h"
+#include "render/object.h"
#include "render/scene.h"
#include "render/shader.h"
#include "render/sobol.h"
@@ -113,6 +115,18 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
}
});
+ const bool need_update_lut = ao_samples_is_modified() || diffuse_samples_is_modified() ||
+ glossy_samples_is_modified() || max_bounce_is_modified() ||
+ max_transmission_bounce_is_modified() ||
+ mesh_light_samples_is_modified() || method_is_modified() ||
+ sampling_pattern_is_modified() ||
+ subsurface_samples_is_modified() ||
+ transmission_samples_is_modified() || volume_samples_is_modified();
+
+ if (need_update_lut) {
+ dscene->sample_pattern_lut.tag_realloc();
+ }
+
device_free(device, dscene);
KernelIntegrator *kintegrator = &dscene->data.integrator;
@@ -242,45 +256,69 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
int dimensions = PRNG_BASE_NUM + max_samples * PRNG_BOUNCE_NUM;
dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
- if (sampling_pattern == SAMPLING_PATTERN_SOBOL) {
- uint *directions = dscene->sample_pattern_lut.alloc(SOBOL_BITS * dimensions);
+ if (need_update_lut) {
+ if (sampling_pattern == SAMPLING_PATTERN_SOBOL) {
+ uint *directions = dscene->sample_pattern_lut.alloc(SOBOL_BITS * dimensions);
- sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
+ sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
- dscene->sample_pattern_lut.copy_to_device();
- }
- else {
- constexpr int sequence_size = NUM_PMJ_SAMPLES;
- constexpr int num_sequences = NUM_PMJ_PATTERNS;
- float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size * num_sequences *
- 2);
- TaskPool pool;
- for (int j = 0; j < num_sequences; ++j) {
- float2 *sequence = directions + j * sequence_size;
- pool.push(
- function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j));
+ dscene->sample_pattern_lut.copy_to_device();
+ }
+ else {
+ constexpr int sequence_size = NUM_PMJ_SAMPLES;
+ constexpr int num_sequences = NUM_PMJ_PATTERNS;
+ float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size *
+ num_sequences * 2);
+ TaskPool pool;
+ for (int j = 0; j < num_sequences; ++j) {
+ float2 *sequence = directions + j * sequence_size;
+ pool.push(
+ function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j));
+ }
+ pool.wait_work();
+ dscene->sample_pattern_lut.copy_to_device();
}
- pool.wait_work();
- dscene->sample_pattern_lut.copy_to_device();
}
+ dscene->sample_pattern_lut.clear_modified();
clear_modified();
}
-void Integrator::device_free(Device *, DeviceScene *dscene)
+void Integrator::device_free(Device *, DeviceScene *dscene, bool force_free)
{
- dscene->sample_pattern_lut.free();
+ dscene->sample_pattern_lut.free_if_need_realloc(force_free);
}
-void Integrator::tag_update(Scene *scene)
+void Integrator::tag_update(Scene *scene, uint32_t flag)
{
- foreach (Shader *shader, scene->shaders) {
- if (shader->has_integrator_dependency) {
- scene->shader_manager->need_update = true;
- break;
+ if (flag & UPDATE_ALL) {
+ tag_modified();
+ }
+
+ if (flag & (AO_PASS_MODIFIED | BACKGROUND_AO_MODIFIED)) {
+ /* tag only the ao_bounces socket as modified so we avoid updating sample_pattern_lut
+ * unnecessarily */
+ tag_ao_bounces_modified();
+ }
+
+ if ((flag & LIGHT_SAMPLES_MODIFIED) && (method == BRANCHED_PATH)) {
+ /* the number of light samples may affect the size of the sample_pattern_lut */
+ tag_sampling_pattern_modified();
+ }
+
+ if (filter_glossy_is_modified()) {
+ foreach (Shader *shader, scene->shaders) {
+ if (shader->has_integrator_dependency) {
+ scene->shader_manager->tag_update(scene, ShaderManager::INTEGRATOR_MODIFIED);
+ break;
+ }
}
}
- tag_modified();
+
+ if (motion_blur_is_modified()) {
+ scene->object_manager->tag_update(scene, ObjectManager::MOTION_BLUR_MODIFIED);
+ scene->camera->tag_modified();
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index 9fe46ad591c..4eeeda92d41 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -89,13 +89,24 @@ class Integrator : public Node {
NODE_SOCKET_API(SamplingPattern, sampling_pattern)
+ enum : uint32_t {
+ AO_PASS_MODIFIED = (1 << 0),
+ BACKGROUND_AO_MODIFIED = (1 << 1),
+ LIGHT_SAMPLES_MODIFIED = (1 << 2),
+
+ /* tag everything in the manager for an update */
+ UPDATE_ALL = ~0u,
+
+ UPDATE_NONE = 0u,
+ };
+
Integrator();
~Integrator();
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_free(Device *device, DeviceScene *dscene, bool force_free = false);
- void tag_update(Scene *scene);
+ void tag_update(Scene *scene, uint32_t flag);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 2bde3242b26..1e54a237816 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -162,7 +162,13 @@ Light::Light() : Node(node_type)
void Light::tag_update(Scene *scene)
{
- scene->light_manager->need_update = is_modified();
+ if (is_modified()) {
+ scene->light_manager->tag_update(scene, LightManager::LIGHT_MODIFIED);
+
+ if (samples_is_modified()) {
+ scene->integrator->tag_update(scene, Integrator::LIGHT_SAMPLES_MODIFIED);
+ }
+ }
}
bool Light::has_contribution(Scene *scene)
@@ -183,7 +189,7 @@ bool Light::has_contribution(Scene *scene)
LightManager::LightManager()
{
- need_update = true;
+ update_flags = UPDATE_ALL;
need_update_background = true;
use_light_visibility = false;
last_background_enabled = false;
@@ -962,7 +968,7 @@ void LightManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
- if (!need_update)
+ if (!need_update())
return;
scoped_callback_timer timer([scene](double time) {
@@ -973,7 +979,7 @@ void LightManager::device_update(Device *device,
VLOG(1) << "Total " << scene->lights.size() << " lights.";
- /* Detect which lights are enabled, also determins if we need to update the background. */
+ /* Detect which lights are enabled, also determines if we need to update the background. */
test_enabled_lights(scene);
device_free(device, dscene, need_update_background);
@@ -1000,7 +1006,7 @@ void LightManager::device_update(Device *device,
scene->film->set_use_light_visibility(use_light_visibility);
- need_update = false;
+ update_flags = UPDATE_NONE;
need_update_background = false;
}
@@ -1015,9 +1021,14 @@ void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_ba
dscene->ies_lights.free();
}
-void LightManager::tag_update(Scene * /*scene*/)
+void LightManager::tag_update(Scene * /*scene*/, uint32_t flag)
+{
+ update_flags |= flag;
+}
+
+bool LightManager::need_update() const
{
- need_update = true;
+ return update_flags != UPDATE_NONE;
}
int LightManager::add_ies_from_file(const string &filename)
@@ -1063,7 +1074,7 @@ int LightManager::add_ies(const string &content)
ies_slots[slot]->users = 1;
ies_slots[slot]->hash = hash;
- need_update = true;
+ update_flags = UPDATE_ALL;
need_update_background = true;
return slot;
@@ -1082,8 +1093,10 @@ void LightManager::remove_ies(int slot)
ies_slots[slot]->users--;
/* If the slot has no more users, update the device to remove it. */
- need_update |= (ies_slots[slot]->users == 0);
- need_update_background |= need_update;
+ if (ies_slots[slot]->users == 0) {
+ update_flags |= UPDATE_ALL;
+ need_update_background = true;
+ }
}
void LightManager::device_update_ies(DeviceScene *dscene)
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index e590e13b489..39014b5d667 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -91,8 +91,23 @@ class Light : public Node {
class LightManager {
public:
+ enum : uint32_t {
+ MESH_NEED_REBUILD = (1 << 0),
+ EMISSIVE_MESH_MODIFIED = (1 << 1),
+ LIGHT_MODIFIED = (1 << 2),
+ LIGHT_ADDED = (1 << 3),
+ LIGHT_REMOVED = (1 << 4),
+ OBJECT_MANAGER = (1 << 5),
+ SHADER_COMPILED = (1 << 6),
+ SHADER_MODIFIED = (1 << 7),
+
+ /* tag everything in the manager for an update */
+ UPDATE_ALL = ~0u,
+
+ UPDATE_NONE = 0u,
+ };
+
bool use_light_visibility;
- bool need_update;
/* Need to update background (including multiple importance map) */
bool need_update_background;
@@ -108,7 +123,9 @@ class LightManager {
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene, const bool free_background = true);
- void tag_update(Scene *scene);
+ void tag_update(Scene *scene, uint32_t flag);
+
+ bool need_update() const;
/* Check whether there is a background light. */
bool has_background_light(Scene *scene);
@@ -145,6 +162,8 @@ class LightManager {
bool last_background_enabled;
int last_background_resolution;
+
+ uint32_t update_flags;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/merge.cpp b/intern/cycles/render/merge.cpp
index 3ea3952b96c..8a58c827e82 100644
--- a/intern/cycles/render/merge.cpp
+++ b/intern/cycles/render/merge.cpp
@@ -151,7 +151,7 @@ static bool parse_channels(const ImageSpec &in_spec,
string layername, passname, channelname;
if (parse_channel_name(
pass.channel_name, layername, passname, channelname, multiview_channels)) {
- /* Channer part of a render layer. */
+ /* Channel part of a render layer. */
pass.op = parse_channel_operation(passname);
}
else {
@@ -163,7 +163,7 @@ static bool parse_channels(const ImageSpec &in_spec,
file_layers[layername].passes.push_back(pass);
}
- /* Loop over all detected RenderLayers, check whether they contain a full set of input channels.
+ /* Loop over all detected render-layers, check whether they contain a full set of input channels.
* Any channels that won't be processed internally are also passed through. */
for (auto &i : file_layers) {
const string &name = i.first;
@@ -457,7 +457,7 @@ static bool save_output(const string &filepath,
out.reset();
- /* Copy temporary file to outputput filepath. */
+ /* Copy temporary file to output filepath. */
string rename_error;
if (ok && !OIIO::Filesystem::rename(tmp_filepath, filepath, rename_error)) {
error = "Failed to move merged image to " + filepath + ": " + rename_error;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index a0afdd3b841..5f62da8f18b 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -805,34 +805,42 @@ void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, ui
}
}
-void Mesh::pack_primitives(PackedBVH &pack, int object, uint visibility)
+void Mesh::pack_primitives(ccl::PackedBVH *pack, int object, uint visibility, bool pack_all)
{
if (triangles.empty())
return;
const size_t num_prims = num_triangles();
- pack.prim_tri_index.reserve(pack.prim_tri_index.size() + num_prims);
- pack.prim_tri_verts.reserve(pack.prim_tri_verts.size() + num_prims * 3);
- pack.prim_type.reserve(pack.prim_type.size() + num_prims);
- pack.prim_visibility.reserve(pack.prim_visibility.size() + num_prims);
- pack.prim_index.reserve(pack.prim_index.size() + num_prims);
- pack.prim_object.reserve(pack.prim_object.size() + num_prims);
- // 'pack.prim_time' is unused by Embree and OptiX
+
+ /* Use prim_offset for indexing as it is computed per geometry type, and prim_tri_verts does not
+ * contain data for Hair geometries. */
+ float4 *prim_tri_verts = &pack->prim_tri_verts[prim_offset * 3];
+ // 'pack->prim_time' is unused by Embree and OptiX
uint type = has_motion_blur() ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE;
- for (size_t k = 0; k < num_prims; ++k) {
- pack.prim_tri_index.push_back_reserved(pack.prim_tri_verts.size());
+ if (pack_all) {
+ /* Use optix_prim_offset for indexing as those arrays also contain data for Hair geometries. */
+ unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
+ int *prim_type = &pack->prim_type[optix_prim_offset];
+ unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
+ int *prim_index = &pack->prim_index[optix_prim_offset];
+ int *prim_object = &pack->prim_object[optix_prim_offset];
+
+ for (size_t k = 0; k < num_prims; ++k) {
+ prim_tri_index[k] = (prim_offset + k) * 3;
+ prim_type[k] = type;
+ prim_index[k] = prim_offset + k;
+ prim_object[k] = object;
+ prim_visibility[k] = visibility;
+ }
+ }
+ for (size_t k = 0; k < num_prims; ++k) {
const Mesh::Triangle t = get_triangle(k);
- pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[0]]));
- pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[1]]));
- pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[2]]));
-
- pack.prim_type.push_back_reserved(type);
- pack.prim_visibility.push_back_reserved(visibility);
- pack.prim_index.push_back_reserved(k + prim_offset);
- pack.prim_object.push_back_reserved(object);
+ prim_tri_verts[k * 3] = float3_to_float4(verts[t.v[0]]);
+ prim_tri_verts[k * 3 + 1] = float3_to_float4(verts[t.v[1]]);
+ prim_tri_verts[k * 3 + 2] = float3_to_float4(verts[t.v[2]]);
}
}
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index b0a16fdfd8f..2b0ff92ab62 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -232,7 +232,7 @@ class Mesh : public Geometry {
size_t tri_offset);
void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
- void pack_primitives(PackedBVH &pack, int object, uint visibility) override;
+ void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) override;
void tessellate(DiagSplit *split);
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 4d51b4fccaf..d4603143ef4 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -1612,7 +1612,7 @@ class OSLNode : public ShaderNode {
SHADER_NODE_NO_CLONE_CLASS(OSLNode)
- /* ideally we could beter detect this, but we can't query this now */
+ /* Ideally we could better detect this, but we can't query this now. */
bool has_spatial_varying()
{
return true;
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 406982e3ef9..e837be9e6fb 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -153,6 +153,10 @@ void Object::update_motion()
void Object::compute_bounds(bool motion_blur)
{
+ if (!is_modified() && !geometry->is_modified()) {
+ return;
+ }
+
BoundBox mbounds = geometry->bounds;
if (motion_blur && use_motion()) {
@@ -205,20 +209,39 @@ void Object::apply_transform(bool apply_to_motion)
void Object::tag_update(Scene *scene)
{
+ uint32_t flag = ObjectManager::UPDATE_NONE;
+
+ if (is_modified()) {
+ flag |= ObjectManager::OBJECT_MODIFIED;
+
+ if (use_holdout_is_modified()) {
+ flag |= ObjectManager::HOLDOUT_MODIFIED;
+ }
+ }
+
if (geometry) {
- if (geometry->transform_applied)
- geometry->tag_modified();
+ if (tfm_is_modified()) {
+ /* tag the geometry as modified so the BVH is updated, but do not tag everything as modified
+ */
+ if (geometry->is_mesh() || geometry->is_volume()) {
+ Mesh *mesh = static_cast<Mesh *>(geometry);
+ mesh->tag_verts_modified();
+ }
+ else if (geometry->is_hair()) {
+ Hair *hair = static_cast<Hair *>(geometry);
+ hair->tag_curve_keys_modified();
+ }
+ }
foreach (Node *node, geometry->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
if (shader->get_use_mis() && shader->has_surface_emission)
- scene->light_manager->need_update = true;
+ scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
}
}
scene->camera->need_flags_update = true;
- scene->geometry_manager->need_update = true;
- scene->object_manager->need_update = true;
+ scene->object_manager->tag_update(scene, flag);
}
bool Object::use_motion() const
@@ -361,7 +384,7 @@ int Object::get_device_index() const
ObjectManager::ObjectManager()
{
- need_update = true;
+ update_flags = UPDATE_ALL;
need_flags_update = true;
}
@@ -382,7 +405,9 @@ static float object_volume_density(const Transform &tfm, Geometry *geom)
return 1.0f;
}
-void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob)
+void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state,
+ Object *ob,
+ bool update_all)
{
KernelObject &kobject = state->objects[ob->index];
Transform *object_motion_pass = state->object_motion_pass;
@@ -456,8 +481,11 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
kobject.motion_offset = state->motion_offset[ob->index];
/* Decompose transforms for interpolation. */
- DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
- transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
+ if (ob->tfm_is_modified() || update_all) {
+ DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
+ transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
+ }
+
flag |= SD_OBJECT_MOTION;
state->have_motion = true;
}
@@ -480,10 +508,14 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
0;
kobject.patch_map_offset = 0;
kobject.attribute_map_offset = 0;
- uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
- uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
- kobject.cryptomatte_object = util_hash_to_float(hash_name);
- kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
+
+ if (ob->asset_name_is_modified() || update_all) {
+ uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
+ uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
+ kobject.cryptomatte_object = util_hash_to_float(hash_name);
+ kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
+ }
+
kobject.shadow_terminator_offset = 1.0f / (1.0f - 0.5f * ob->shadow_terminator_offset);
/* Object flag. */
@@ -544,6 +576,9 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
numparticles += psys->particles.size();
}
+ /* as all the arrays are the same size, checking only dscene.objects is sufficient */
+ const bool update_all = dscene->objects.need_realloc();
+
/* Parallel object update, with grain size to avoid too much threading overhead
* for individual objects. */
static const int OBJECTS_PER_TASK = 32;
@@ -551,7 +586,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
[&](const blocked_range<size_t> &r) {
for (size_t i = r.begin(); i != r.end(); i++) {
Object *ob = state.scene->objects[i];
- device_update_object_transform(&state, ob);
+ device_update_object_transform(&state, ob, update_all);
}
});
@@ -559,7 +594,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
return;
}
- dscene->objects.copy_to_device();
+ dscene->objects.copy_to_device_if_modified();
if (state.need_motion == Scene::MOTION_PASS) {
dscene->object_motion_pass.copy_to_device();
}
@@ -569,6 +604,10 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
dscene->data.bvh.have_motion = state.have_motion;
dscene->data.bvh.have_curves = state.have_curves;
+
+ dscene->objects.clear_modified();
+ dscene->object_motion_pass.clear_modified();
+ dscene->object_motion.clear_modified();
}
void ObjectManager::device_update(Device *device,
@@ -576,12 +615,28 @@ void ObjectManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
- if (!need_update)
+ if (!need_update())
return;
+ if (update_flags & (OBJECT_ADDED | OBJECT_REMOVED)) {
+ dscene->objects.tag_realloc();
+ dscene->object_motion_pass.tag_realloc();
+ dscene->object_motion.tag_realloc();
+ dscene->object_flag.tag_realloc();
+ dscene->object_volume_step.tag_realloc();
+ }
+
+ if (update_flags & HOLDOUT_MODIFIED) {
+ dscene->object_flag.tag_modified();
+ }
+
+ if (update_flags & PARTICLE_MODIFIED) {
+ dscene->objects.tag_modified();
+ }
+
VLOG(1) << "Total " << scene->objects.size() << " objects.";
- device_free(device, dscene);
+ device_free(device, dscene, false);
if (scene->objects.size() == 0)
return;
@@ -597,6 +652,16 @@ void ObjectManager::device_update(Device *device,
int index = 0;
foreach (Object *object, scene->objects) {
object->index = index++;
+
+ /* this is a bit too broad, however a bigger refactor might be needed to properly separate
+ * update each type of data (transform, flags, etc.) */
+ if (object->is_modified()) {
+ dscene->objects.tag_modified();
+ dscene->object_motion_pass.tag_modified();
+ dscene->object_motion.tag_modified();
+ dscene->object_flag.tag_modified();
+ dscene->object_volume_step.tag_modified();
+ }
}
}
@@ -638,7 +703,7 @@ void ObjectManager::device_update(Device *device,
void ObjectManager::device_update_flags(
Device *, DeviceScene *dscene, Scene *scene, Progress & /*progress*/, bool bounds_valid)
{
- if (!need_update && !need_flags_update)
+ if (!need_update() && !need_flags_update)
return;
scoped_callback_timer timer([scene](double time) {
@@ -647,7 +712,7 @@ void ObjectManager::device_update_flags(
}
});
- need_update = false;
+ update_flags = UPDATE_NONE;
need_flags_update = false;
if (scene->objects.size() == 0)
@@ -717,6 +782,9 @@ void ObjectManager::device_update_flags(
/* Copy object flag. */
dscene->object_flag.copy_to_device();
dscene->object_volume_step.copy_to_device();
+
+ dscene->object_flag.clear_modified();
+ dscene->object_volume_step.clear_modified();
}
void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Scene *scene)
@@ -764,13 +832,13 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc
}
}
-void ObjectManager::device_free(Device *, DeviceScene *dscene)
+void ObjectManager::device_free(Device *, DeviceScene *dscene, bool force_free)
{
- dscene->objects.free();
- dscene->object_motion_pass.free();
- dscene->object_motion.free();
- dscene->object_flag.free();
- dscene->object_volume_step.free();
+ dscene->objects.free_if_need_realloc(force_free);
+ dscene->object_motion_pass.free_if_need_realloc(force_free);
+ dscene->object_motion.free_if_need_realloc(force_free);
+ dscene->object_flag.free_if_need_realloc(force_free);
+ dscene->object_volume_step.free_if_need_realloc(force_free);
}
void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
@@ -841,11 +909,29 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
}
}
-void ObjectManager::tag_update(Scene *scene)
+void ObjectManager::tag_update(Scene *scene, uint32_t flag)
+{
+ update_flags |= flag;
+
+ /* avoid infinite loops if the geometry manager tagged us for an update */
+ if ((flag & GEOMETRY_MANAGER) == 0) {
+ uint32_t geometry_flag = GeometryManager::OBJECT_MANAGER;
+
+ /* Also notify in case added or removed objects were instances, as no Geometry might have been
+ * added or removed, but the BVH still needs to updated. */
+ if ((flag & (OBJECT_ADDED | OBJECT_REMOVED)) != 0) {
+ geometry_flag |= (GeometryManager::GEOMETRY_ADDED | GeometryManager::GEOMETRY_REMOVED);
+ }
+
+ scene->geometry_manager->tag_update(scene, geometry_flag);
+ }
+
+ scene->light_manager->tag_update(scene, LightManager::OBJECT_MANAGER);
+}
+
+bool ObjectManager::need_update() const
{
- need_update = true;
- scene->geometry_manager->need_update = true;
- scene->light_manager->need_update = true;
+ return update_flags != UPDATE_NONE;
}
string ObjectManager::get_cryptomatte_objects(Scene *scene)
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 76c9c30abb0..cf1b9ca510a 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -122,8 +122,24 @@ class Object : public Node {
/* Object Manager */
class ObjectManager {
+ uint32_t update_flags;
+
public:
- bool need_update;
+ enum : uint32_t {
+ PARTICLE_MODIFIED = (1 << 0),
+ GEOMETRY_MANAGER = (1 << 1),
+ MOTION_BLUR_MODIFIED = (1 << 2),
+ OBJECT_ADDED = (1 << 3),
+ OBJECT_REMOVED = (1 << 4),
+ OBJECT_MODIFIED = (1 << 5),
+ HOLDOUT_MODIFIED = (1 << 6),
+
+ /* tag everything in the manager for an update */
+ UPDATE_ALL = ~0u,
+
+ UPDATE_NONE = 0u,
+ };
+
bool need_flags_update;
ObjectManager();
@@ -139,9 +155,11 @@ class ObjectManager {
bool bounds_valid = true);
void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene);
- void device_free(Device *device, DeviceScene *dscene);
+ void device_free(Device *device, DeviceScene *dscene, bool force_free);
- void tag_update(Scene *scene);
+ void tag_update(Scene *scene, uint32_t flag);
+
+ bool need_update() const;
void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress);
@@ -149,7 +167,9 @@ class ObjectManager {
string get_cryptomatte_assets(Scene *scene);
protected:
- void device_update_object_transform(UpdateObjectTransformState *state, Object *ob);
+ void device_update_object_transform(UpdateObjectTransformState *state,
+ Object *ob,
+ bool update_all);
void device_update_object_transform_task(UpdateObjectTransformState *state);
bool device_update_object_transform_pop_work(UpdateObjectTransformState *state,
int *start_index,
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 35b62746f1b..53c67049571 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -96,7 +96,7 @@ void OSLShaderManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
- if (!need_update)
+ if (!need_update())
return;
scoped_callback_timer timer([scene](double time) {
@@ -132,7 +132,7 @@ void OSLShaderManager::device_update(Device *device,
compiler.compile(og, shader);
if (shader->get_use_mis() && shader->has_surface_emission)
- scene->light_manager->need_update = true;
+ scene->light_manager->tag_update(scene, LightManager::SHADER_COMPILED);
}
/* setup shader engine */
@@ -147,7 +147,7 @@ void OSLShaderManager::device_update(Device *device,
foreach (Shader *shader, scene->shaders)
shader->clear_modified();
- need_update = false;
+ update_flags = UPDATE_NONE;
/* add special builtin texture types */
services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
@@ -380,7 +380,7 @@ const char *OSLShaderManager::shader_load_filepath(string filepath)
return hash;
}
- /* autocompile .OSL to .OSO if needed */
+ /* Auto-compile .OSL to .OSO if needed. */
if (oso_modified_time == 0 || (oso_modified_time < modified_time)) {
OSLShaderManager::osl_compile(filepath, osopath);
modified_time = path_modified_time(osopath);
@@ -562,7 +562,7 @@ OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph,
}
}
- /* set bytcode hash or filepath */
+ /* Set byte-code hash or file-path. */
if (!bytecode_hash.empty()) {
node->bytecode_hash = bytecode_hash;
}
diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp
index faad731d413..0e168050281 100644
--- a/intern/cycles/render/particles.cpp
+++ b/intern/cycles/render/particles.cpp
@@ -46,14 +46,14 @@ ParticleSystem::~ParticleSystem()
void ParticleSystem::tag_update(Scene *scene)
{
- scene->particle_system_manager->need_update = true;
+ scene->particle_system_manager->tag_update(scene);
}
/* Particle System Manager */
ParticleSystemManager::ParticleSystemManager()
{
- need_update = true;
+ need_update_ = true;
}
ParticleSystemManager::~ParticleSystemManager()
@@ -109,7 +109,7 @@ void ParticleSystemManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
- if (!need_update)
+ if (!need_update())
return;
scoped_callback_timer timer([scene](double time) {
@@ -128,7 +128,7 @@ void ParticleSystemManager::device_update(Device *device,
if (progress.get_cancel())
return;
- need_update = false;
+ need_update_ = false;
}
void ParticleSystemManager::device_free(Device *, DeviceScene *dscene)
@@ -138,7 +138,12 @@ void ParticleSystemManager::device_free(Device *, DeviceScene *dscene)
void ParticleSystemManager::tag_update(Scene * /*scene*/)
{
- need_update = true;
+ need_update_ = true;
+}
+
+bool ParticleSystemManager::need_update() const
+{
+ return need_update_;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/particles.h b/intern/cycles/render/particles.h
index 0b0408184fe..8b59756f148 100644
--- a/intern/cycles/render/particles.h
+++ b/intern/cycles/render/particles.h
@@ -57,9 +57,9 @@ class ParticleSystem : public Node {
/* ParticleSystem Manager */
class ParticleSystemManager {
- public:
- bool need_update;
+ bool need_update_;
+ public:
ParticleSystemManager();
~ParticleSystemManager();
@@ -71,6 +71,8 @@ class ParticleSystemManager {
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene);
+
+ bool need_update() const;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/procedural.cpp b/intern/cycles/render/procedural.cpp
new file mode 100644
index 00000000000..1307a35dcf2
--- /dev/null
+++ b/intern/cycles/render/procedural.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2011-2018 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "procedural.h"
+
+#include "render/scene.h"
+#include "render/stats.h"
+
+#include "util/util_foreach.h"
+#include "util/util_progress.h"
+
+CCL_NAMESPACE_BEGIN
+
+NODE_ABSTRACT_DEFINE(Procedural)
+{
+ NodeType *type = NodeType::add("procedural_base", NULL);
+ return type;
+}
+
+Procedural::Procedural(const NodeType *type) : Node(type)
+{
+}
+
+Procedural::~Procedural()
+{
+}
+
+ProceduralManager::ProceduralManager()
+{
+ need_update_ = true;
+}
+
+ProceduralManager::~ProceduralManager()
+{
+}
+
+void ProceduralManager::update(Scene *scene, Progress &progress)
+{
+ if (!need_update()) {
+ return;
+ }
+
+ progress.set_status("Updating Procedurals");
+
+ scoped_callback_timer timer([scene](double time) {
+ if (scene->update_stats) {
+ scene->update_stats->procedurals.times.add_entry({"update", time});
+ }
+ });
+
+ foreach (Procedural *procedural, scene->procedurals) {
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ procedural->generate(scene, progress);
+ }
+
+ if (progress.get_cancel()) {
+ return;
+ }
+
+ need_update_ = false;
+}
+
+void ProceduralManager::tag_update()
+{
+ need_update_ = true;
+}
+
+bool ProceduralManager::need_update() const
+{
+ return need_update_;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/procedural.h b/intern/cycles/render/procedural.h
new file mode 100644
index 00000000000..985b8d69979
--- /dev/null
+++ b/intern/cycles/render/procedural.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-2018 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "graph/node.h"
+
+CCL_NAMESPACE_BEGIN
+
+class Progress;
+class Scene;
+
+/* A Procedural is a Node which can create other Nodes before rendering starts.
+ *
+ * The Procedural is supposed to be the owner of any nodes that it creates. It can also create
+ * Nodes directly in the Scene (through Scene.create_node), it should still be set as the owner of
+ * those Nodes.
+ */
+class Procedural : public Node, public NodeOwner {
+ public:
+ NODE_ABSTRACT_DECLARE
+
+ explicit Procedural(const NodeType *type);
+ virtual ~Procedural();
+
+ /* Called each time the ProceduralManager is tagged for an update, this function is the entry
+ * point for the data generated by this Procedural. */
+ virtual void generate(Scene *scene, Progress &progress) = 0;
+
+ /* Create a node and set this Procedural as the owner. */
+ template<typename T> T *create_node()
+ {
+ T *node = new T();
+ node->set_owner(this);
+ return node;
+ }
+
+ /* Delete a Node created and owned by this Procedural. */
+ template<typename T> void delete_node(T *node)
+ {
+ assert(node->get_owner() == this);
+ delete node;
+ }
+};
+
+class ProceduralManager {
+ bool need_update_;
+
+ public:
+ ProceduralManager();
+ ~ProceduralManager();
+
+ void update(Scene *scene, Progress &progress);
+
+ void tag_update();
+
+ bool need_update() const;
+};
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index b7720b7aa99..6bb25677965 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -18,6 +18,7 @@
#include "bvh/bvh.h"
#include "device/device.h"
+#include "render/alembic.h"
#include "render/background.h"
#include "render/bake.h"
#include "render/camera.h"
@@ -29,6 +30,7 @@
#include "render/object.h"
#include "render/osl.h"
#include "render/particles.h"
+#include "render/procedural.h"
#include "render/scene.h"
#include "render/session.h"
#include "render/shader.h"
@@ -114,6 +116,7 @@ Scene::Scene(const SceneParams &params_, Device *device)
image_manager = new ImageManager(device->info);
particle_system_manager = new ParticleSystemManager();
bake_manager = new BakeManager();
+ procedural_manager = new ProceduralManager();
kernels_loaded = false;
/* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
@@ -142,6 +145,9 @@ void Scene::free_memory(bool final)
foreach (Shader *s, shaders)
delete s;
+ /* delete procedurals before other types as they may hold pointers to those types */
+ foreach (Procedural *p, procedurals)
+ delete p;
foreach (Geometry *g, geometry)
delete g;
foreach (Object *o, objects)
@@ -156,15 +162,16 @@ void Scene::free_memory(bool final)
objects.clear();
lights.clear();
particle_systems.clear();
+ procedurals.clear();
if (device) {
camera->device_free(device, &dscene, this);
film->device_free(device, &dscene, this);
background->device_free(device, &dscene);
- integrator->device_free(device, &dscene);
+ integrator->device_free(device, &dscene, true);
- object_manager->device_free(device, &dscene);
- geometry_manager->device_free(device, &dscene);
+ object_manager->device_free(device, &dscene, true);
+ geometry_manager->device_free(device, &dscene, true);
shader_manager->device_free(device, &dscene, this);
light_manager->device_free(device, &dscene);
@@ -195,6 +202,7 @@ void Scene::free_memory(bool final)
delete image_manager;
delete bake_manager;
delete update_stats;
+ delete procedural_manager;
}
}
@@ -236,6 +244,11 @@ void Scene::device_update(Device *device_, Progress &progress)
if (progress.get_cancel() || device->have_error())
return;
+ procedural_manager->update(this, progress);
+
+ if (progress.get_cancel())
+ return;
+
progress.set_status("Updating Background");
background->device_update(device, &dscene, this);
@@ -386,11 +399,12 @@ bool Scene::need_update()
bool Scene::need_data_update()
{
- return (background->is_modified() || image_manager->need_update || object_manager->need_update ||
- geometry_manager->need_update || light_manager->need_update ||
- lookup_tables->need_update || integrator->is_modified() || shader_manager->need_update ||
- particle_system_manager->need_update || bake_manager->need_update ||
- film->is_modified());
+ return (background->is_modified() || image_manager->need_update() ||
+ object_manager->need_update() || geometry_manager->need_update() ||
+ light_manager->need_update() || lookup_tables->need_update() ||
+ integrator->is_modified() || shader_manager->need_update() ||
+ particle_system_manager->need_update() || bake_manager->need_update() ||
+ film->is_modified() || procedural_manager->need_update());
}
bool Scene::need_reset()
@@ -407,12 +421,15 @@ void Scene::reset()
camera->tag_modified();
dicing_camera->tag_modified();
film->tag_modified();
+ background->tag_modified();
+
background->tag_update(this);
- integrator->tag_update(this);
- object_manager->tag_update(this);
- geometry_manager->tag_update(this);
- light_manager->tag_update(this);
+ integrator->tag_update(this, Integrator::UPDATE_ALL);
+ object_manager->tag_update(this, ObjectManager::UPDATE_ALL);
+ geometry_manager->tag_update(this, GeometryManager::UPDATE_ALL);
+ light_manager->tag_update(this, LightManager::UPDATE_ALL);
particle_system_manager->tag_update(this);
+ procedural_manager->tag_update();
}
void Scene::device_free()
@@ -596,7 +613,7 @@ template<> Light *Scene::create_node<Light>()
Light *node = new Light();
node->set_owner(this);
lights.push_back(node);
- light_manager->tag_update(this);
+ light_manager->tag_update(this, LightManager::LIGHT_ADDED);
return node;
}
@@ -605,7 +622,7 @@ template<> Mesh *Scene::create_node<Mesh>()
Mesh *node = new Mesh();
node->set_owner(this);
geometry.push_back(node);
- geometry_manager->tag_update(this);
+ geometry_manager->tag_update(this, GeometryManager::MESH_ADDED);
return node;
}
@@ -614,7 +631,7 @@ template<> Hair *Scene::create_node<Hair>()
Hair *node = new Hair();
node->set_owner(this);
geometry.push_back(node);
- geometry_manager->tag_update(this);
+ geometry_manager->tag_update(this, GeometryManager::HAIR_ADDED);
return node;
}
@@ -623,7 +640,7 @@ template<> Volume *Scene::create_node<Volume>()
Volume *node = new Volume();
node->set_owner(this);
geometry.push_back(node);
- geometry_manager->tag_update(this);
+ geometry_manager->tag_update(this, GeometryManager::MESH_ADDED);
return node;
}
@@ -632,7 +649,7 @@ template<> Object *Scene::create_node<Object>()
Object *node = new Object();
node->set_owner(this);
objects.push_back(node);
- object_manager->tag_update(this);
+ object_manager->tag_update(this, ObjectManager::OBJECT_ADDED);
return node;
}
@@ -650,10 +667,23 @@ template<> Shader *Scene::create_node<Shader>()
Shader *node = new Shader();
node->set_owner(this);
shaders.push_back(node);
- shader_manager->need_update = true;
+ shader_manager->tag_update(this, ShaderManager::SHADER_ADDED);
return node;
}
+template<> AlembicProcedural *Scene::create_node<AlembicProcedural>()
+{
+#ifdef WITH_ALEMBIC
+ AlembicProcedural *node = new AlembicProcedural();
+ node->set_owner(this);
+ procedurals.push_back(node);
+ procedural_manager->tag_update();
+ return node;
+#else
+ return nullptr;
+#endif
+}
+
template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
{
for (size_t i = 0; i < nodes.size(); ++i) {
@@ -664,43 +694,52 @@ template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
}
nodes.resize(nodes.size() - 1);
+
delete node;
}
template<> void Scene::delete_node_impl(Light *node)
{
delete_node_from_array(lights, node);
- light_manager->tag_update(this);
+ light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
}
template<> void Scene::delete_node_impl(Mesh *node)
{
delete_node_from_array(geometry, static_cast<Geometry *>(node));
- geometry_manager->tag_update(this);
+ geometry_manager->tag_update(this, GeometryManager::MESH_REMOVED);
}
template<> void Scene::delete_node_impl(Hair *node)
{
delete_node_from_array(geometry, static_cast<Geometry *>(node));
- geometry_manager->tag_update(this);
+ geometry_manager->tag_update(this, GeometryManager::HAIR_REMOVED);
}
template<> void Scene::delete_node_impl(Volume *node)
{
delete_node_from_array(geometry, static_cast<Geometry *>(node));
- geometry_manager->tag_update(this);
+ geometry_manager->tag_update(this, GeometryManager::MESH_REMOVED);
}
template<> void Scene::delete_node_impl(Geometry *node)
{
+ uint flag;
+ if (node->is_hair()) {
+ flag = GeometryManager::HAIR_REMOVED;
+ }
+ else {
+ flag = GeometryManager::MESH_REMOVED;
+ }
+
delete_node_from_array(geometry, node);
- geometry_manager->tag_update(this);
+ geometry_manager->tag_update(this, flag);
}
template<> void Scene::delete_node_impl(Object *node)
{
delete_node_from_array(objects, node);
- object_manager->tag_update(this);
+ object_manager->tag_update(this, ObjectManager::OBJECT_REMOVED);
}
template<> void Scene::delete_node_impl(ParticleSystem *node)
@@ -714,6 +753,21 @@ template<> void Scene::delete_node_impl(Shader * /*node*/)
/* don't delete unused shaders, not supported */
}
+template<> void Scene::delete_node_impl(Procedural *node)
+{
+ delete_node_from_array(procedurals, node);
+ procedural_manager->tag_update();
+}
+
+template<> void Scene::delete_node_impl(AlembicProcedural *node)
+{
+#ifdef WITH_ALEMBIC
+ delete_node_impl(static_cast<Procedural *>(node));
+#else
+ (void)node;
+#endif
+}
+
template<typename T>
static void remove_nodes_in_set(const set<T *> &nodes_set,
vector<T *> &nodes_array,
@@ -742,19 +796,19 @@ static void remove_nodes_in_set(const set<T *> &nodes_set,
template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner)
{
remove_nodes_in_set(nodes, lights, owner);
- light_manager->tag_update(this);
+ light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
}
template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner)
{
remove_nodes_in_set(nodes, geometry, owner);
- geometry_manager->tag_update(this);
+ geometry_manager->tag_update(this, GeometryManager::GEOMETRY_REMOVED);
}
template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner)
{
remove_nodes_in_set(nodes, objects, owner);
- object_manager->tag_update(this);
+ object_manager->tag_update(this, ObjectManager::OBJECT_REMOVED);
}
template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner)
@@ -768,4 +822,10 @@ template<> void Scene::delete_nodes(const set<Shader *> & /*nodes*/, const NodeO
/* don't delete unused shaders, not supported */
}
+template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner)
+{
+ remove_nodes_in_set(nodes, procedurals, owner);
+ procedural_manager->tag_update();
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 27e9a131bbd..61c753e411c 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -36,6 +36,7 @@
CCL_NAMESPACE_BEGIN
+class AlembicProcedural;
class AttributeRequestSet;
class Background;
class BVH;
@@ -53,6 +54,8 @@ class Object;
class ObjectManager;
class ParticleSystemManager;
class ParticleSystem;
+class Procedural;
+class ProceduralManager;
class CurveSystemManager;
class Shader;
class ShaderManager;
@@ -236,6 +239,7 @@ class Scene : public NodeOwner {
vector<Light *> lights;
vector<ParticleSystem *> particle_systems;
vector<Pass> passes;
+ vector<Procedural *> procedurals;
/* data managers */
ImageManager *image_manager;
@@ -245,6 +249,7 @@ class Scene : public NodeOwner {
ObjectManager *object_manager;
ParticleSystemManager *particle_system_manager;
BakeManager *bake_manager;
+ ProceduralManager *procedural_manager;
/* default shaders */
Shader *default_surface;
@@ -353,7 +358,7 @@ class Scene : public NodeOwner {
DeviceRequestedFeatures get_requested_device_features();
- /* Maximumnumber of closure during session lifetime. */
+ /* Maximum number of closure during session lifetime. */
int max_closure_global;
/* Get maximum number of closures to be used in kernel. */
@@ -379,6 +384,8 @@ template<> ParticleSystem *Scene::create_node<ParticleSystem>();
template<> Shader *Scene::create_node<Shader>();
+template<> AlembicProcedural *Scene::create_node<AlembicProcedural>();
+
template<> void Scene::delete_node_impl(Light *node);
template<> void Scene::delete_node_impl(Mesh *node);
@@ -395,6 +402,10 @@ template<> void Scene::delete_node_impl(ParticleSystem *node);
template<> void Scene::delete_node_impl(Shader *node);
+template<> void Scene::delete_node_impl(Procedural *node);
+
+template<> void Scene::delete_node_impl(AlembicProcedural *node);
+
template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner);
template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner);
@@ -405,6 +416,8 @@ template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const No
template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner *owner);
+template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner);
+
CCL_NAMESPACE_END
#endif /* __SCENE_H__ */
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 7a30ecb24f7..3c601e18126 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -1040,13 +1040,7 @@ bool Session::update_scene()
BakeManager *bake_manager = scene->bake_manager;
if (integrator->get_sampling_pattern() != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) {
- int aa_samples = tile_manager.num_samples;
-
- integrator->set_aa_samples(aa_samples);
-
- if (integrator->is_modified()) {
- integrator->tag_update(scene);
- }
+ integrator->set_aa_samples(tile_manager.num_samples);
}
bool kernel_switch_needed = false;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 7e06b427e4d..332599be708 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -16,6 +16,7 @@
#include "device/device.h"
+#include "render/alembic.h"
#include "render/background.h"
#include "render/camera.h"
#include "render/colorspace.h"
@@ -218,7 +219,9 @@ Shader::Shader() : Node(node_type)
id = -1;
used = false;
- need_update_geometry = true;
+ need_update_uvs = true;
+ need_update_attribute = true;
+ need_update_displacement = true;
}
Shader::~Shader()
@@ -291,7 +294,7 @@ void Shader::set_graph(ShaderGraph *graph_)
const char *new_hash = (graph_) ? graph_->displacement_hash.c_str() : "";
if (strcmp(old_hash, new_hash) != 0) {
- need_update_geometry = true;
+ need_update_displacement = true;
}
}
@@ -308,13 +311,14 @@ void Shader::tag_update(Scene *scene)
{
/* update tag */
tag_modified();
- scene->shader_manager->need_update = true;
+
+ scene->shader_manager->tag_update(scene, ShaderManager::SHADER_MODIFIED);
/* if the shader previously was emissive, update light distribution,
* if the new shader is emissive, a light manager update tag will be
* done in the shader manager device update. */
if (use_mis && has_surface_emission)
- scene->light_manager->need_update = true;
+ scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
/* Special handle of background MIS light for now: for some reason it
* has use_mis set to false. We are quite close to release now, so
@@ -323,7 +327,7 @@ void Shader::tag_update(Scene *scene)
if (this == scene->background->get_shader(scene)) {
scene->light_manager->need_update_background = true;
if (scene->light_manager->has_background_light(scene)) {
- scene->light_manager->need_update = true;
+ scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
}
}
@@ -352,17 +356,18 @@ void Shader::tag_update(Scene *scene)
attributes.add(ATTR_STD_POSITION_UNDISPLACED);
}
if (displacement_method_is_modified()) {
- need_update_geometry = true;
- scene->geometry_manager->need_update = true;
+ need_update_displacement = true;
+ scene->geometry_manager->tag_update(scene, GeometryManager::SHADER_DISPLACEMENT_MODIFIED);
scene->object_manager->need_flags_update = true;
}
}
/* compare if the attributes changed, mesh manager will check
- * need_update_geometry, update the relevant meshes and clear it. */
+ * need_update_attribute, update the relevant meshes and clear it. */
if (attributes.modified(prev_attributes)) {
- need_update_geometry = true;
- scene->geometry_manager->need_update = true;
+ need_update_attribute = true;
+ scene->geometry_manager->tag_update(scene, GeometryManager::SHADER_ATTRIBUTE_MODIFIED);
+ scene->procedural_manager->tag_update();
}
if (has_volume != prev_has_volume || volume_step_rate != prev_volume_step_rate) {
@@ -378,15 +383,20 @@ void Shader::tag_used(Scene *scene)
* recompiled because it was skipped for compilation before */
if (!used) {
tag_modified();
- scene->shader_manager->need_update = true;
+ scene->shader_manager->tag_update(scene, ShaderManager::SHADER_MODIFIED);
}
}
+bool Shader::need_update_geometry() const
+{
+ return need_update_uvs || need_update_attribute || need_update_displacement;
+}
+
/* Shader Manager */
ShaderManager::ShaderManager()
{
- need_update = true;
+ update_flags = UPDATE_ALL;
beckmann_table_offset = TABLE_OFFSET_INVALID;
xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
@@ -484,7 +494,7 @@ int ShaderManager::get_shader_id(Shader *shader, bool smooth)
void ShaderManager::update_shaders_used(Scene *scene)
{
- if (!need_update) {
+ if (!need_update()) {
return;
}
@@ -504,6 +514,21 @@ void ShaderManager::update_shaders_used(Scene *scene)
if (scene->background->get_shader())
scene->background->get_shader()->used = true;
+#ifdef WITH_ALEMBIC
+ foreach (Procedural *procedural, scene->procedurals) {
+ AlembicProcedural *abc_proc = static_cast<AlembicProcedural *>(procedural);
+
+ foreach (Node *abc_node, abc_proc->get_objects()) {
+ AlembicObject *abc_object = static_cast<AlembicObject *>(abc_node);
+
+ foreach (Node *node, abc_object->get_used_shaders()) {
+ Shader *shader = static_cast<Shader *>(node);
+ shader->used = true;
+ }
+ }
+ }
+#endif
+
foreach (Geometry *geom, scene->geometry)
foreach (Node *node, geom->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
@@ -793,4 +818,15 @@ string ShaderManager::get_cryptomatte_materials(Scene *scene)
return manifest;
}
+void ShaderManager::tag_update(Scene * /*scene*/, uint32_t /*flag*/)
+{
+ /* update everything for now */
+ update_flags = ShaderManager::UPDATE_ALL;
+}
+
+bool ShaderManager::need_update() const
+{
+ return update_flags != UPDATE_NONE;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index de19048d8e1..4375ef9e978 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -100,7 +100,9 @@ class Shader : public Node {
float prev_volume_step_rate;
/* synchronization */
- bool need_update_geometry;
+ bool need_update_uvs;
+ bool need_update_attribute;
+ bool need_update_displacement;
/* If the shader has only volume components, the surface is assumed to
* be transparent.
@@ -152,6 +154,8 @@ class Shader : public Node {
void set_graph(ShaderGraph *graph);
void tag_update(Scene *scene);
void tag_used(Scene *scene);
+
+ bool need_update_geometry() const;
};
/* Shader Manager virtual base class
@@ -161,7 +165,16 @@ class Shader : public Node {
class ShaderManager {
public:
- bool need_update;
+ enum : uint32_t {
+ SHADER_ADDED = (1 << 0),
+ SHADER_MODIFIED = (1 << 2),
+ INTEGRATOR_MODIFIED = (1 << 3),
+
+ /* tag everything in the manager for an update */
+ UPDATE_ALL = ~0u,
+
+ UPDATE_NONE = 0u,
+ };
static ShaderManager *create(int shadingsystem);
virtual ~ShaderManager();
@@ -204,9 +217,15 @@ class ShaderManager {
string get_cryptomatte_materials(Scene *scene);
+ void tag_update(Scene *scene, uint32_t flag);
+
+ bool need_update() const;
+
protected:
ShaderManager();
+ uint32_t update_flags;
+
typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
AttributeIDMap unique_attribute_id;
diff --git a/intern/cycles/render/stats.cpp b/intern/cycles/render/stats.cpp
index 1a840a906a5..2c6273842e2 100644
--- a/intern/cycles/render/stats.cpp
+++ b/intern/cycles/render/stats.cpp
@@ -375,6 +375,7 @@ string SceneUpdateStats::full_report()
result += "Particles:\n" + particles.full_report(1);
result += "SVM:\n" + svm.full_report(1);
result += "Tables:\n" + tables.full_report(1);
+ result += "Procedurals:\n" + procedurals.full_report(1);
return result;
}
@@ -394,6 +395,7 @@ void SceneUpdateStats::clear()
scene.times.clear();
svm.times.clear();
tables.times.clear();
+ procedurals.times.clear();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/stats.h b/intern/cycles/render/stats.h
index a6be27db4c2..93d029bba61 100644
--- a/intern/cycles/render/stats.h
+++ b/intern/cycles/render/stats.h
@@ -219,6 +219,7 @@ class SceneUpdateStats {
UpdateTimeStats scene;
UpdateTimeStats svm;
UpdateTimeStats tables;
+ UpdateTimeStats procedurals;
string full_report();
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 6f5a03124f2..fce604234f1 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -74,7 +74,7 @@ void SVMShaderManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
- if (!need_update)
+ if (!need_update())
return;
scoped_callback_timer timer([scene](double time) {
@@ -125,7 +125,7 @@ void SVMShaderManager::device_update(Device *device,
shader->clear_modified();
if (shader->get_use_mis() && shader->has_surface_emission) {
- scene->light_manager->need_update = true;
+ scene->light_manager->tag_update(scene, LightManager::SHADER_COMPILED);
}
/* Update the global jump table.
@@ -159,7 +159,7 @@ void SVMShaderManager::device_update(Device *device,
device_update_common(device, dscene, scene, progress);
- need_update = false;
+ update_flags = UPDATE_NONE;
VLOG(1) << "Shader manager updated " << num_shaders << " shaders in " << time_dt() - start_time
<< " seconds.";
diff --git a/intern/cycles/render/tables.cpp b/intern/cycles/render/tables.cpp
index b581537c852..a0813400b1c 100644
--- a/intern/cycles/render/tables.cpp
+++ b/intern/cycles/render/tables.cpp
@@ -28,7 +28,7 @@ CCL_NAMESPACE_BEGIN
LookupTables::LookupTables()
{
- need_update = true;
+ need_update_ = true;
}
LookupTables::~LookupTables()
@@ -38,7 +38,7 @@ LookupTables::~LookupTables()
void LookupTables::device_update(Device *, DeviceScene *dscene, Scene *scene)
{
- if (!need_update)
+ if (!need_update())
return;
scoped_callback_timer timer([scene](double time) {
@@ -52,7 +52,7 @@ void LookupTables::device_update(Device *, DeviceScene *dscene, Scene *scene)
if (lookup_tables.size() > 0)
dscene->lookup_table.copy_to_device();
- need_update = false;
+ need_update_ = false;
}
void LookupTables::device_free(Device *, DeviceScene *dscene)
@@ -60,6 +60,11 @@ void LookupTables::device_free(Device *, DeviceScene *dscene)
dscene->lookup_table.free();
}
+bool LookupTables::need_update() const
+{
+ return need_update_;
+}
+
static size_t round_up_to_multiple(size_t size, size_t chunk)
{
return ((size + chunk - 1) / chunk) * chunk;
@@ -69,7 +74,7 @@ size_t LookupTables::add_table(DeviceScene *dscene, vector<float> &data)
{
assert(data.size() > 0);
- need_update = true;
+ need_update_ = true;
Table new_table;
new_table.offset = 0;
@@ -107,7 +112,7 @@ void LookupTables::remove_table(size_t *offset)
return;
}
- need_update = true;
+ need_update_ = true;
list<Table>::iterator table;
diff --git a/intern/cycles/render/tables.h b/intern/cycles/render/tables.h
index e912d9c01f4..de538e2af78 100644
--- a/intern/cycles/render/tables.h
+++ b/intern/cycles/render/tables.h
@@ -30,13 +30,14 @@ enum { TABLE_CHUNK_SIZE = 256 };
enum { TABLE_OFFSET_INVALID = -1 };
class LookupTables {
+ bool need_update_;
+
public:
struct Table {
size_t offset;
size_t size;
};
- bool need_update;
list<Table> lookup_tables;
LookupTables();
@@ -45,6 +46,8 @@ class LookupTables {
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene);
+ bool need_update() const;
+
size_t add_table(DeviceScene *dscene, vector<float> &data);
void remove_table(size_t *offset);
};
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index 928f5bf2ed7..4d648eb1f77 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -549,7 +549,7 @@ void DiagSplit::split_ngon(const Mesh::SubdFace &face, Patch *patches, size_t pa
subpatch.edge_v1.indices_decrease_along_edge = true;
subpatch.edge_u0.indices_decrease_along_edge = u0_reversed;
- /* Perfrom split. */
+ /* Perform split. */
{
subpatch.edge_u0.T = T(subpatch.patch, subpatch.c00, subpatch.c10);
subpatch.edge_u1.T = T(subpatch.patch, subpatch.c01, subpatch.c11);
@@ -646,7 +646,7 @@ void DiagSplit::post_split()
/* Set start and end indices for edges generated from a split. */
foreach (Edge &edge, edges) {
if (edge.start_vert_index < 0) {
- /* Fixup offsets. */
+ /* Fix up offsets. */
if (edge.top_indices_decrease) {
edge.top_offset = edge.top->T - edge.top_offset;
}
diff --git a/intern/cycles/subd/subd_split.h b/intern/cycles/subd/subd_split.h
index 773f4ddf120..7416b2fbbf8 100644
--- a/intern/cycles/subd/subd_split.h
+++ b/intern/cycles/subd/subd_split.h
@@ -40,7 +40,7 @@ class DiagSplit {
SubdParams params;
vector<Subpatch> subpatches;
- /* deque is used so that element pointers remain vaild when size is changed. */
+ /* `deque` is used so that element pointers remain valid when size is changed. */
deque<Edge> edges;
float3 to_world(Patch *patch, float2 uv);
diff --git a/intern/cycles/util/util_array.h b/intern/cycles/util/util_array.h
index ea481787018..73f7d6cf7f8 100644
--- a/intern/cycles/util/util_array.h
+++ b/intern/cycles/util/util_array.h
@@ -131,6 +131,14 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra
}
}
+ void set_data(T *ptr_, size_t datasize)
+ {
+ clear();
+ data_ = ptr_;
+ datasize_ = datasize;
+ capacity_ = datasize;
+ }
+
T *steal_pointer()
{
T *ptr = data_;
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 8caabf6eac3..ad04340231e 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -349,7 +349,7 @@ ccl_device_inline float fractf(float x)
return x - floorf(x);
}
-/* Adapted from godotengine math_funcs.h. */
+/* Adapted from godot-engine math_funcs.h. */
ccl_device_inline float wrapf(float value, float max, float min)
{
float range = max - min;
@@ -385,7 +385,7 @@ ccl_device_inline float nonzerof(float f, float eps)
return f;
}
-/* Signum function testing for zero. Matches GLSL and OSL functions. */
+/* `signum` function testing for zero. Matches GLSL and OSL functions. */
ccl_device_inline float compatible_signf(float f)
{
if (f == 0.0f) {
@@ -754,7 +754,7 @@ ccl_device_inline float2 map_to_sphere(const float3 co)
float u, v;
if (l > 0.0f) {
if (UNLIKELY(co.x == 0.0f && co.y == 0.0f)) {
- u = 0.0f; /* othwise domain error */
+ u = 0.0f; /* Otherwise domain error. */
}
else {
u = (1.0f - atan2f(co.x, co.y) / M_PI_F) / 2.0f;
diff --git a/intern/cycles/util/util_math_fast.h b/intern/cycles/util/util_math_fast.h
index 07b0878e3d5..107b36ce6cd 100644
--- a/intern/cycles/util/util_math_fast.h
+++ b/intern/cycles/util/util_math_fast.h
@@ -84,7 +84,7 @@ ccl_device_inline int fast_rint(float x)
{
/* used by sin/cos/tan range reduction. */
#ifdef __KERNEL_SSE4__
- /* Single roundps instruction on SSE4.1+ (for gcc/clang at least). */
+ /* Single `roundps` instruction on SSE4.1+ (for gcc/clang at least). */
return float_to_int(rintf(x));
#else
/* emulate rounding by adding/subtracting 0.5. */
@@ -613,7 +613,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. */
+ /* From: Approximating the `erfinv` function by Mike Giles. */
/* To avoid trouble at the limit, clamp input to 1-eps. */
float a = fabsf(x);
if (a > 0.99999994f) {
diff --git a/intern/cycles/util/util_math_matrix.h b/intern/cycles/util/util_math_matrix.h
index 1dc661a7aa7..123736f75a6 100644
--- a/intern/cycles/util/util_math_matrix.h
+++ b/intern/cycles/util/util_math_matrix.h
@@ -161,7 +161,7 @@ ccl_device_inline void math_trimatrix_add_gramian(ccl_global float *A,
}
}
-/* Transpose matrix A inplace. */
+/* Transpose matrix A in place. */
ccl_device_inline void math_matrix_transpose(ccl_global float *A, int n, int stride)
{
for (int i = 0; i < n; i++) {
diff --git a/intern/cycles/util/util_md5.h b/intern/cycles/util/util_md5.h
index 4622945f9d2..3102a0f4bad 100644
--- a/intern/cycles/util/util_md5.h
+++ b/intern/cycles/util/util_md5.h
@@ -49,7 +49,7 @@ class MD5Hash {
void process(const uint8_t *data);
void finish(uint8_t digest[16]);
- uint32_t count[2]; /* message length in bits, lsw first */
+ uint32_t count[2]; /* message length in bits, LSW first. */
uint32_t abcd[4]; /* digest buffer */
uint8_t buf[64]; /* accumulate block */
};
diff --git a/intern/cycles/util/util_stack_allocator.h b/intern/cycles/util/util_stack_allocator.h
index 36db655e5eb..ef31c0fe5e2 100644
--- a/intern/cycles/util/util_stack_allocator.h
+++ b/intern/cycles/util/util_stack_allocator.h
@@ -126,7 +126,7 @@ template<int SIZE, typename T> class ccl_try_align(16) StackAllocator
return size_t(-1);
}
- /* Rebind to other ype of allocator. */
+ /* Rebind to other type of allocator. */
template<class U> struct rebind {
typedef StackAllocator<SIZE, U> other;
diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h
index f51aa7111e8..6b6f493bd94 100644
--- a/intern/cycles/util/util_string.h
+++ b/intern/cycles/util/util_string.h
@@ -66,9 +66,9 @@ string string_from_wstring(const wstring &path);
string string_to_ansi(const string &str);
#endif
-/* Make a string from a size in bytes in human readable form */
+/* Make a string from a size in bytes in human readable form. */
string string_human_readable_size(size_t size);
-/* Make a string from a unitless quantity in human readable form */
+/* Make a string from a unit-less quantity in human readable form. */
string string_human_readable_number(size_t num);
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_tbb.h b/intern/cycles/util/util_tbb.h
index 168bd5db961..73e0f92d19c 100644
--- a/intern/cycles/util/util_tbb.h
+++ b/intern/cycles/util/util_tbb.h
@@ -21,11 +21,14 @@
* WIN32_LEAN_AND_MEAN and similar are defined beforehand. */
#include "util_windows.h"
-#define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
-#include <tbb/tbb.h>
+#include <tbb/enumerable_thread_specific.h>
+#include <tbb/parallel_for.h>
+#include <tbb/task_arena.h>
+#include <tbb/task_group.h>
#if TBB_INTERFACE_VERSION_MAJOR >= 10
# define WITH_TBB_GLOBAL_CONTROL
+# include <tbb/global_control.h>
#endif
CCL_NAMESPACE_BEGIN
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index d6eb5f9db1d..727fd4b9601 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -49,16 +49,6 @@
#include <libswscale/swscale.h>
-/* Stupid way to distinguish FFmpeg from Libav:
- * - FFmpeg's MICRO version starts from 100 and goes up, while
- * - Libav's micro is always below 100.
- */
-#if LIBAVCODEC_VERSION_MICRO >= 100
-# define AV_USING_FFMPEG
-#else
-# define AV_USING_LIBAV
-#endif
-
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105))
# define FFMPEG_HAVE_AVIO 1
@@ -528,22 +518,6 @@ bool av_check_encoded_with_ffmpeg(AVFormatContext *ctx)
return false;
}
-/* Libav doesn't have av_guess_frame_rate().
- * It was introduced in FFmpeg's lavf 55.1.100. */
-#ifdef AV_USING_LIBAV
-AVRational av_guess_frame_rate(AVFormatContext *ctx, AVStream *stream, AVFrame *frame)
-{
- (void)ctx;
- (void)frame;
-# if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 23, 1)
- /* For until r_frame_rate was deprecated (in Libav) use it. */
- return stream->r_frame_rate;
-# else
- return stream->avg_frame_rate;
-# endif
-}
-#endif
-
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 32, 0)
# define AV_OPT_SEARCH_FAKE_OBJ 0
#endif
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 2bc73f7eb22..d79111b742f 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -25,6 +25,8 @@
#include "GHOST_Types.h"
+#include <stdbool.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -160,6 +162,7 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
* The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
* \param systemhandle: The handle to the system.
+ * \param parentWindow: Handle of parent (or owner) window, or NULL
* \param title: The name of the window.
* (displayed in the title bar of the window if the OS supports it).
* \param left: The coordinate of the left edge of the window.
@@ -167,31 +170,23 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
* \param width: The width the window.
* \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).
*/
extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
+ GHOST_WindowHandle parent_windowhandle,
const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
GHOST_TUns32 height,
GHOST_TWindowState state,
+ bool is_dialog,
GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings);
-extern GHOST_WindowHandle GHOST_CreateDialogWindow(GHOST_SystemHandle systemhandle,
- GHOST_WindowHandle parent_windowhandle,
- const char *title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings);
-
/**
* Create a new offscreen context.
* Never explicitly delete the context, use disposeContext() instead.
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 8bce064ce63..bd7ba6657f0 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -580,7 +580,7 @@ typedef struct {
GHOST_TUns32 xPixels;
/** Number of lines. */
GHOST_TUns32 yPixels;
- /** Numberof bits per pixel. */
+ /** Number of bits per pixel. */
GHOST_TUns32 bpp;
/** Refresh rate (in Hertz). */
GHOST_TUns32 frequency;
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index e4bb908fec8..af65e1cd4d2 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -153,34 +153,19 @@ GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
}
GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
+ GHOST_WindowHandle parent_windowhandle,
const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
GHOST_TUns32 height,
GHOST_TWindowState state,
+ bool is_dialog,
GHOST_TDrawingContextType type,
GHOST_GLSettings glSettings)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return (GHOST_WindowHandle)system->createWindow(
- title, left, top, width, height, state, type, glSettings, false, false);
-}
-
-GHOST_WindowHandle GHOST_CreateDialogWindow(GHOST_SystemHandle systemhandle,
- GHOST_WindowHandle parent_windowhandle,
- const char *title,
- GHOST_TInt32 left,
- GHOST_TInt32 top,
- GHOST_TUns32 width,
- GHOST_TUns32 height,
- GHOST_TWindowState state,
- GHOST_TDrawingContextType type,
- GHOST_GLSettings glSettings)
-{
- GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
-
return (GHOST_WindowHandle)system->createWindow(title,
left,
top,
@@ -190,7 +175,7 @@ GHOST_WindowHandle GHOST_CreateDialogWindow(GHOST_SystemHandle systemhandle,
type,
glSettings,
false,
- true,
+ is_dialog,
(GHOST_IWindow *)parent_windowhandle);
}
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index d07913b28c4..810b78a7d39 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -127,8 +127,8 @@ class GHOST_Context : public GHOST_IContext {
}
/**
- * Gets the OpenGL framebuffer associated with the OpenGL context
- * \return The ID of an OpenGL framebuffer object.
+ * Gets the OpenGL frame-buffer associated with the OpenGL context
+ * \return The ID of an OpenGL frame-buffer object.
*/
virtual unsigned int getDefaultFramebuffer()
{
diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h
index d499ec987b0..8e4376236fa 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.h
+++ b/intern/ghost/intern/GHOST_ContextCGL.h
@@ -115,10 +115,10 @@ class GHOST_ContextCGL : public GHOST_Context {
/** The OpenGL drawing context */
NSOpenGLContext *m_openGLContext;
- /** The virtualized default framebuffer */
+ /** The virtualized default frame-buffer. */
unsigned int m_defaultFramebuffer;
- /** The virtualized default framebuffer's texture */
+ /** The virtualized default frame-buffer's texture. */
MTLTexture *m_defaultFramebufferMetalTexture;
bool m_coreProfile;
diff --git a/intern/ghost/intern/GHOST_ContextD3D.h b/intern/ghost/intern/GHOST_ContextD3D.h
index 18b4a5d1286..8b9537ca439 100644
--- a/intern/ghost/intern/GHOST_ContextD3D.h
+++ b/intern/ghost/intern/GHOST_ContextD3D.h
@@ -97,8 +97,8 @@ class GHOST_ContextD3D : public GHOST_Context {
}
/**
- * Gets the OpenGL framebuffer associated with the OpenGL context
- * \return The ID of an OpenGL framebuffer object.
+ * Gets the OpenGL frame-buffer associated with the OpenGL context
+ * \return The ID of an OpenGL frame-buffer object.
*/
unsigned int getDefaultFramebuffer()
{
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
index 424f95aa573..13858410c5a 100644
--- a/intern/ghost/intern/GHOST_Debug.h
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -26,7 +26,7 @@
#ifdef _MSC_VER
# ifdef DEBUG
-/* Suppress stl-MSVC debug info warning. */
+/* Suppress STL-MSVC debug info warning. */
# pragma warning(disable : 4786)
# endif
#endif
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp
index 816d9c254ee..82ed9de230d 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp
@@ -203,7 +203,7 @@ void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dr
GHOST_TStringArray *strArray = NULL;
int totPaths = 0, curLength = 0;
- /* count total number of file pathes in buffer */
+ /* 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 (curLength) {
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.h b/intern/ghost/intern/GHOST_DropTargetX11.h
index 69f6fec7ac1..f538dbbb617 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.h
+++ b/intern/ghost/intern/GHOST_DropTargetX11.h
@@ -103,22 +103,22 @@ class GHOST_DropTargetX11 {
/* Data type of the dragged object */
GHOST_TDragnDropTypes m_draggedObjectType;
- /* is dnd stuff initialzied */
+ /* Is drag-and-drop stuff initialized. */
static bool m_xdndInitialized;
- /* class holding internal stiff of xdnd library */
+ /* Class holding internal stiff of `xdnd` library. */
static DndClass m_dndClass;
- /* list of supported types to eb draggeg into */
+ /* List of supported types to be dragged into. */
static Atom *m_dndTypes;
- /* list of supported dran'n'drop actions */
+ /* List of supported drag-and-drop actions. */
static Atom *m_dndActions;
- /* List of supported MIME types to be dragged into */
+ /* List of supported MIME types to be dragged into. */
static const char *m_dndMimeTypes[];
- /* counter of references to global XDND structures */
+ /* Counter of references to global #XDND structures. */
static int m_refCounter;
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h
index 63ecfd96cb8..cbef0f0edc4 100644
--- a/intern/ghost/intern/GHOST_ImeWin32.h
+++ b/intern/ghost/intern/GHOST_ImeWin32.h
@@ -303,10 +303,10 @@ class GHOST_ImeWin32 {
*/
void EndIME(HWND window_handle);
- /* Updatg resultInfo and compInfo */
+ /** Update #resultInfo and #compInfo */
void UpdateInfo(HWND window_handle);
- /* disable ime when start up */
+ /** Disable IME when start up. */
void CheckFirst(HWND window_handle);
ImeComposition resultInfo, compInfo;
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
index 193633b5c3e..47e71b0d733 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
@@ -40,7 +40,7 @@ GHOST_SystemPathsWin32::~GHOST_SystemPathsWin32()
const GHOST_TUns8 *GHOST_SystemPathsWin32::getSystemDir(int, const char *versionstr) const
{
- /* 1 utf-16 might translante into 3 utf-8. 2 utf-16 translates into 4 utf-8*/
+ /* 1 utf-16 might translate into 3 utf-8. 2 utf-16 translates into 4 utf-8. */
static char knownpath[MAX_PATH * 3 + 128] = {0};
PWSTR knownpath_16 = NULL;
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 718ace9db4a..b71b6b9e170 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -963,7 +963,7 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
processCursorEvent(window);
}
else {
- /* Tablet should be hadling inbetween mouse moves, only move to event position. */
+ /* Tablet should be handling in between mouse moves, only move to event position. */
DWORD msgPos = ::GetMessagePos();
int msgPosX = GET_X_LPARAM(msgPos);
int msgPosY = GET_Y_LPARAM(msgPos);
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 8e7b966aadf..9152aa22495 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -23,7 +23,7 @@
* \ingroup GHOST
*/
-#include <X11/XKBlib.h> /* Allow detectable auto-repeate. */
+#include <X11/XKBlib.h> /* Allow detectable auto-repeat. */
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
@@ -185,10 +185,10 @@ GHOST_SystemX11::GHOST_SystemX11() : GHOST_System(), m_xkb_descr(NULL), m_start_
GHOST_ASSERT(false, "Could not instantiate timer!");
}
- /* Taking care not to overflow the tv.tv_sec * 1000 */
+ /* Taking care not to overflow the `tv.tv_sec * 1000`. */
m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
- /* Use detectable auto-repeate, mac and windows also do this. */
+ /* Use detectable auto-repeat, mac and windows also do this. */
int use_xkb;
int xkb_opcode, xkb_event, xkb_error;
int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion;
@@ -528,7 +528,7 @@ bool GHOST_SystemX11::openX11_IM()
if (!m_display)
return false;
- /* set locale modifiers such as "@im=ibus" specified by XMODIFIERS */
+ /* set locale modifiers such as `@im=ibus` specified by XMODIFIERS. */
XSetLocaleModifiers("");
m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
@@ -1146,7 +1146,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
*/
if ((xke->keycode >= 10 && xke->keycode < 20) &&
((key_sym = XLookupKeysym(xke, ShiftMask)) >= XK_0) && (key_sym <= XK_9)) {
- /* pass (keep shift'ed key_sym) */
+ /* Pass (keep shifted `key_sym`). */
}
else {
/* regular case */
@@ -1161,12 +1161,12 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
#endif
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- /* getting unicode on key-up events gives XLookupNone status */
+ /* Setting unicode on key-up events gives #XLookupNone status. */
XIC xic = window->getX11_XIC();
if (xic && xke->type == KeyPress) {
Status status;
- /* use utf8 because its not locale depentant, from xorg docs */
+ /* Use utf8 because its not locale repentant, from XORG docs. */
if (!(len = Xutf8LookupString(
xic, xke, utf8_buf, sizeof(utf8_array) - 5, &key_sym, &status))) {
utf8_buf[0] = '\0';
@@ -1269,8 +1269,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
gbmask = GHOST_kButtonMaskRight;
/* It seems events 6 and 7 are for horizontal scrolling.
* you can re-order button mapping like this... (swaps 6,7 with 8,9)
- * xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"
- */
+ * `xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"` */
else if (xbe.button == 6)
gbmask = GHOST_kButtonMaskButton6;
else if (xbe.button == 7)
@@ -1289,8 +1288,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
/* change of size, border, layer etc. */
case ConfigureNotify: {
- /* XConfigureEvent & xce = xe->xconfigure; */
-
+ // XConfigureEvent & xce = xe->xconfigure;
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
break;
}
@@ -1934,8 +1932,8 @@ static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCo
#define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */
#define XCLIB_XCOUT_INCR 2 /* in an incr loop */
#define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */
-#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */
-#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */
+#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compound. */
+#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compound failed, move to text. */
#define XCLIB_XCOUT_FALLBACK_TEXT 6
/* Retrieves the contents of a selections. */
@@ -2198,30 +2196,30 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
restore_events.push_back(evt);
}
- /* fallback is needed. set XA_STRING to target and restart the loop. */
+ /* Fallback is needed. Set #XA_STRING to target and restart the loop. */
if (context == XCLIB_XCOUT_FALLBACK) {
context = XCLIB_XCOUT_NONE;
target = m_atom.STRING;
continue;
}
else if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
- /* utf8 fail, move to compouned text. */
+ /* utf8 fail, move to compound text. */
context = XCLIB_XCOUT_NONE;
target = m_atom.COMPOUND_TEXT;
continue;
}
else if (context == XCLIB_XCOUT_FALLBACK_COMP) {
- /* compouned text fail, move to text. */
+ /* Compound text fail, move to text. */
context = XCLIB_XCOUT_NONE;
target = m_atom.TEXT;
continue;
}
else if (context == XCLIB_XCOUT_FALLBACK_TEXT) {
- /* text fail, nothing else to try, break. */
+ /* Text fail, nothing else to try, break. */
context = XCLIB_XCOUT_NONE;
}
- /* only continue if xcout() is doing something */
+ /* Only continue if #xcout() is doing something. */
if (context == XCLIB_XCOUT_NONE)
break;
}
@@ -2232,9 +2230,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
}
if (sel_len) {
- /* only print the buffer out, and free it, if it's not
- * empty
- */
+ /* Only print the buffer out, and free it, if it's not empty. */
unsigned char *tmp_data = (unsigned char *)malloc(sel_len + 1);
memcpy((char *)tmp_data, (char *)sel_buf, sel_len);
tmp_data[sel_len] = '\0';
@@ -2288,28 +2284,28 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
* \{ */
class DialogData {
public:
- /* Width of the dialog */
+ /* Width of the dialog. */
uint width;
- /* Heigth of the dialog */
+ /* Height of the dialog. */
uint height;
- /* Default padding (x direction) between controls and edge of dialog */
+ /* Default padding (x direction) between controls and edge of dialog. */
uint padding_x;
- /* Default padding (y direction) between controls and edge of dialog */
+ /* Default padding (y direction) between controls and edge of dialog. */
uint padding_y;
- /* Width of a single button */
+ /* Width of a single button. */
uint button_width;
- /* Height of a single button */
+ /* Height of a single button. */
uint button_height;
- /* Inset of a button to its text */
+ /* Inset of a button to its text. */
uint button_inset_x;
- /* Size of the border of the button */
+ /* Size of the border of the button. */
uint button_border_size;
/* Height of a line of text */
uint line_height;
- /* offset of the text inside the button */
+ /* Offset of the text inside the button. */
uint button_text_offset_y;
- /* Construct a new DialogData with the default settings */
+ /* Construct a new #DialogData with the default settings. */
DialogData()
: width(640),
height(175),
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index bcebda66ae3..a7e325bc9e1 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -24,7 +24,7 @@
#pragma once
-#include <X11/XKBlib.h> /* Allow detectable auto-repeate. */
+#include <X11/XKBlib.h> /* Allow detectable auto-repeat. */
#include <X11/Xlib.h>
#include "../GHOST_Types.h"
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index d897fafc003..1f2fed5b823 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -392,7 +392,7 @@ class GHOST_Window : public GHOST_IWindow {
/** Stores whether this is a full screen window. */
bool m_fullScreen;
- /** Whether to attempt to initialize a context with a stereo framebuffer. */
+ /** Whether to attempt to initialize a context with a stereo frame-buffer. */
bool m_wantStereoVisual;
/** Full-screen width */
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 255d487649b..18aa19c0863 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -88,103 +88,55 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_fpGetPointerInfoHistory(NULL),
m_fpGetPointerPenInfoHistory(NULL),
m_fpGetPointerTouchInfoHistory(NULL),
- m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : NULL),
+ m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : HWND_DESKTOP),
m_debug_context(is_debug)
{
- // Create window
- if (state != GHOST_kWindowStateFullScreen) {
- RECT rect;
- MONITORINFO monitor;
- GHOST_TUns32 tw, th;
-
-#ifndef _MSC_VER
- int cxsizeframe = GetSystemMetrics(SM_CXSIZEFRAME);
- int cysizeframe = GetSystemMetrics(SM_CYSIZEFRAME);
-#else
- // MSVC 2012+ returns bogus values from GetSystemMetrics, bug in Windows
- // http://connect.microsoft.com/VisualStudio/feedback/details/753224/regression-getsystemmetrics-delivers-different-values
- RECT cxrect = {0, 0, 0, 0};
- AdjustWindowRectEx(
- &cxrect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0);
-
- int cxsizeframe = abs(cxrect.bottom);
- int cysizeframe = abs(cxrect.left);
-#endif
-
- width += cxsizeframe * 2;
- height += cysizeframe * 2 + GetSystemMetrics(SM_CYCAPTION);
+ wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
+ RECT win_rect = {left, top, left + width, top + height};
+ RECT parent_rect = {0, 0, 0, 0};
+ if (parentwindow) {
+ GetWindowRect(m_parentWindowHwnd, &parent_rect);
+ }
- rect.left = left;
- rect.right = left + width;
- rect.top = top;
- rect.bottom = top + height;
+ DWORD style = parentwindow ?
+ WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX :
+ WS_OVERLAPPEDWINDOW;
- monitor.cbSize = sizeof(monitor);
- monitor.dwFlags = 0;
+ if (state == GHOST_kWindowStateFullScreen) {
+ style |= WS_MAXIMIZE;
+ }
- // take taskbar into account
- GetMonitorInfo(MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST), &monitor);
+ /* Forces owned windows onto taskbar and allows minimization. */
+ DWORD extended_style = parentwindow ? WS_EX_APPWINDOW : 0;
- th = monitor.rcWork.bottom - monitor.rcWork.top;
- tw = monitor.rcWork.right - monitor.rcWork.left;
+ /* Monitor details. */
+ MONITORINFOEX monitor;
+ monitor.cbSize = sizeof(MONITORINFOEX);
+ monitor.dwFlags = 0;
+ GetMonitorInfo(
+ MonitorFromRect(parentwindow ? &parent_rect : &win_rect, MONITOR_DEFAULTTONEAREST),
+ &monitor);
- if (tw < width) {
- width = tw;
- left = monitor.rcWork.left;
- }
- else if (monitor.rcWork.right < left + (int)width)
- left = monitor.rcWork.right - width;
- else if (left < monitor.rcWork.left)
- left = monitor.rcWork.left;
-
- if (th < height) {
- height = th;
- top = monitor.rcWork.top;
- }
- else if (monitor.rcWork.bottom < top + (int)height)
- top = monitor.rcWork.bottom - height;
- else if (top < monitor.rcWork.top)
- top = monitor.rcWork.top;
-
- int wintype = WS_OVERLAPPEDWINDOW;
- if ((m_parentWindowHwnd != 0) && !dialog) {
- wintype = WS_CHILD;
- GetWindowRect(m_parentWindowHwnd, &rect);
- left = 0;
- top = 0;
- width = rect.right - rect.left;
- height = rect.bottom - rect.top;
- }
+ /* Adjust our requested size to allow for caption and borders and constrain to monitor. */
+ AdjustWindowRectEx(&win_rect, WS_CAPTION, FALSE, 0);
+ width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect.right - win_rect.left);
+ left = min(max(monitor.rcWork.left, win_rect.left), monitor.rcWork.right - width);
+ height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect.bottom - win_rect.top);
+ top = min(max(monitor.rcWork.top, win_rect.top), monitor.rcWork.bottom - height);
- wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
- m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name
- title_16, // pointer to window name
- wintype, // window style
- left, // horizontal position of window
- top, // vertical position of window
- width, // window width
- height, // window height
- dialog ? 0 : m_parentWindowHwnd, // handle to parent or owner window
- 0, // handle to menu or child-window identifier
- ::GetModuleHandle(0), // handle to application instance
- 0); // pointer to window-creation data
- free(title_16);
- }
- else {
- wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
- m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name
+ m_hWnd = ::CreateWindowExW(extended_style, // window extended style
+ s_windowClassName, // pointer to registered class name
title_16, // pointer to window name
- WS_MAXIMIZE, // window style
+ style, // window style
left, // horizontal position of window
top, // vertical position of window
width, // window width
height, // window height
- HWND_DESKTOP, // handle to parent or owner window
+ m_parentWindowHwnd, // handle to parent or owner window
0, // handle to menu or child-window identifier
::GetModuleHandle(0), // handle to application instance
0); // pointer to window-creation data
- free(title_16);
- }
+ free(title_16);
m_user32 = ::LoadLibrary("user32.dll");
@@ -268,14 +220,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
}
}
- if (dialog && parentwindow) {
- ::SetWindowLongPtr(
- m_hWnd, GWL_STYLE, WS_VISIBLE | WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_SIZEBOX);
- ::SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)m_parentWindowHwnd);
- ::SetWindowPos(
- m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
- }
- else if (parentwindow) {
+ if (parentwindow && !dialog) {
RAWINPUTDEVICE device = {0};
device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/
device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
@@ -1423,7 +1368,7 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
GHOST_TUns32 fullBitRow, fullMaskRow;
int x, y, cols;
- cols = sizeX / 8; /* Num of whole bytes per row (width of bm/mask) */
+ cols = sizeX / 8; /* Number of whole bytes per row (width of bm/mask). */
if (sizeX % 8)
cols++;
@@ -1462,7 +1407,7 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
GHOST_TSuccess GHOST_WindowWin32::setProgressBar(float progress)
{
- /*SetProgressValue sets state to TBPF_NORMAL automaticly*/
+ /* #SetProgressValue sets state to #TBPF_NORMAL automatically. */
if (m_Bar && S_OK == m_Bar->SetProgressValue(m_hWnd, 10000 * progress, 10000))
return GHOST_kSuccess;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index a7e7cdc6602..661d80c02aa 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -573,7 +573,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
/** Pointer to system. */
GHOST_SystemWin32 *m_system;
- /** Pointer to COM IDropTarget implementor. */
+ /** Pointer to COM #IDropTarget implementer. */
GHOST_DropTargetWin32 *m_dropTarget;
/** Window handle. */
HWND m_hWnd;
@@ -582,14 +582,16 @@ class GHOST_WindowWin32 : public GHOST_Window {
/** Flag for if window has captured the mouse. */
bool m_hasMouseCaptured;
- /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab().
- * Multiple grabs must be released with a single ungrab. */
+ /**
+ * Flag if an operator grabs the mouse with #WM_cursor_grab_enable, #WM_cursor_grab_disable
+ * Multiple grabs must be released with a single un-grab.
+ */
bool m_hasGrabMouse;
/** Count of number of pressed buttons. */
int m_nPressedButtons;
/** HCURSOR structure of the custom cursor. */
HCURSOR m_customCursor;
- /** Request GL context aith alpha channel. */
+ /** Request GL context with alpha channel. */
bool m_wantAlphaBackground;
/** ITaskbarList3 structure for progress bar. */
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 9a38631adb9..fc006c62803 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -293,55 +293,18 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
m_display, RootWindow(m_display, m_visualInfo->screen), m_visualInfo->visual, AllocNone);
/* create the window! */
- if ((parentWindow == 0) || is_dialog) {
- m_window = XCreateWindow(m_display,
- RootWindow(m_display, m_visualInfo->screen),
- left,
- top,
- width,
- height,
- 0, /* no border. */
- m_visualInfo->depth,
- InputOutput,
- m_visualInfo->visual,
- xattributes_valuemask,
- &xattributes);
- }
- else {
- Window root_return;
- int x_return, y_return;
- unsigned int w_return, h_return, border_w_return, depth_return;
-
- XGetGeometry(m_display,
- parentWindow->m_window,
- &root_return,
- &x_return,
- &y_return,
- &w_return,
- &h_return,
- &border_w_return,
- &depth_return);
-
- left = 0;
- top = 0;
- width = w_return;
- height = h_return;
-
- m_window = XCreateWindow(m_display,
- parentWindow->m_window, /* reparent against embedder */
- left,
- top,
- width,
- height,
- 0, /* no border. */
- m_visualInfo->depth,
- InputOutput,
- m_visualInfo->visual,
- xattributes_valuemask,
- &xattributes);
-
- XSelectInput(m_display, parentWindow->m_window, SubstructureNotifyMask);
- }
+ m_window = XCreateWindow(m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ left,
+ top,
+ width,
+ height,
+ 0, /* no border. */
+ m_visualInfo->depth,
+ InputOutput,
+ m_visualInfo->visual,
+ xattributes_valuemask,
+ &xattributes);
#ifdef WITH_XDND
/* initialize drop target for newly created window */
@@ -1169,7 +1132,7 @@ GHOST_TSuccess GHOST_WindowX11::setOrder(GHOST_TWindowOrder order)
XGetWindowAttributes(m_display, m_window, &attr);
- /* iconized windows give bad match error */
+ /* Minimized windows give bad match error. */
if (attr.map_state == IsViewable)
XSetInputFocus(m_display, m_window, RevertToPointerRoot, CurrentTime);
XFlush(m_display);
diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
index 39b7f0776e1..30a2a238ccd 100644
--- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
+++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
@@ -125,7 +125,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
oxr_binding.wgl.hGLRC = ctx_wgl.m_hGLRC;
#endif
- /* Generate a framebuffer to use for blitting into the texture. */
+ /* Generate a frame-buffer to use for blitting into the texture. */
glGenFramebuffers(1, &m_fbo);
}
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 73b73a8f046..a1fd7fc2781 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -338,7 +338,7 @@ void GHOST_XrSession::endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *
void GHOST_XrSession::draw(void *draw_customdata)
{
std::vector<XrCompositionLayerProjectionView>
- projection_layer_views; /* Keep alive until xrEndFrame() call! */
+ projection_layer_views; /* Keep alive until #xrEndFrame() call! */
XrCompositionLayerProjection proj_layer;
std::vector<XrCompositionLayerBaseHeader *> layers;
@@ -354,7 +354,7 @@ void GHOST_XrSession::draw(void *draw_customdata)
static void copy_openxr_pose_to_ghost_pose(const XrPosef &oxr_pose, GHOST_XrPose &r_ghost_pose)
{
- /* Set and convert to Blender coodinate space. */
+ /* Set and convert to Blender coordinate space. */
r_ghost_pose.position[0] = oxr_pose.position.x;
r_ghost_pose.position[1] = oxr_pose.position.y;
r_ghost_pose.position[2] = oxr_pose.position.z;
@@ -366,7 +366,7 @@ static void copy_openxr_pose_to_ghost_pose(const XrPosef &oxr_pose, GHOST_XrPose
static void ghost_xr_draw_view_info_from_view(const XrView &view, GHOST_XrDrawViewInfo &r_info)
{
- /* Set and convert to Blender coodinate space. */
+ /* Set and convert to Blender coordinate space. */
copy_openxr_pose_to_ghost_pose(view.pose, r_info.eye_pose);
r_info.fov.angle_left = view.fov.angleLeft;
diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt
index 27a764cd050..37bb00332dd 100644
--- a/intern/ghost/test/CMakeLists.txt
+++ b/intern/ghost/test/CMakeLists.txt
@@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.5)
project(GhostMultiTest)
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../../..//build_files/cmake/Modules")
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../../../build_files/cmake/Modules")
set(WITH_GUARDEDALLOC ON)
diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c
index 3419f70dfcf..4283f990cfb 100644
--- a/intern/ghost/test/gears/GHOST_C-Test.c
+++ b/intern/ghost/test/gears/GHOST_C-Test.c
@@ -440,12 +440,14 @@ int main(int argc, char **argv)
if (shSystem) {
/* Create the main window */
sMainWindow = GHOST_CreateWindow(shSystem,
+ NULL,
title1,
10,
64,
320,
200,
GHOST_kWindowStateNormal,
+ false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
if (!sMainWindow) {
@@ -455,12 +457,14 @@ int main(int argc, char **argv)
/* Create a secondary window */
sSecondaryWindow = GHOST_CreateWindow(shSystem,
+ NULL,
title2,
340,
64,
320,
200,
GHOST_kWindowStateNormal,
+ false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
if (!sSecondaryWindow) {
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
index b6b83f2a47d..8c8858fc6d8 100644
--- a/intern/ghost/test/multitest/MultiTest.c
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -318,12 +318,14 @@ MainWindow *mainwindow_new(MultiTestApp *app)
GHOST_GLSettings glSettings = {0};
win = GHOST_CreateWindow(sys,
+ NULL,
"MultiTest:Main",
40,
40,
400,
400,
GHOST_kWindowStateNormal,
+ false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
@@ -573,12 +575,14 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]);
win = GHOST_CreateWindow(sys,
+ NULL,
"MultiTest:Logger",
40,
screensize[1] - 432,
800,
300,
GHOST_kWindowStateNormal,
+ false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
@@ -773,12 +777,14 @@ ExtraWindow *extrawindow_new(MultiTestApp *app)
GHOST_WindowHandle win;
win = GHOST_CreateWindow(sys,
+ NULL,
"MultiTest:Extra",
500,
40,
400,
400,
GHOST_kWindowStateNormal,
+ false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index 0d46e81cd87..b47565b8ef9 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -49,12 +49,6 @@ set(LIB
)
if(WIN32 AND NOT UNIX)
- list(APPEND SRC
- intern/mmap_win.c
-
- mmap_win.h
- )
-
list(APPEND INC_SYS
${PTHREADS_INC}
)
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index a0174e30aff..62f28c9e97e 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -122,7 +122,7 @@ extern void *(*MEM_calloc_arrayN)(size_t len,
/**
* Allocate a block of memory of size len, with tag name str. The
* name must be a static, because only a pointer to it is stored !
- * */
+ */
extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
@@ -130,7 +130,7 @@ extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_
* Allocate a block of memory of size (len * size), with tag name str,
* aborting in case of integer overflow to prevent vulnerabilities. The
* name must be a static, because only a pointer to it is stored !
- * */
+ */
extern void *(*MEM_malloc_arrayN)(size_t len,
size_t size,
const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
@@ -139,7 +139,7 @@ extern void *(*MEM_malloc_arrayN)(size_t len,
/**
* Allocate an aligned block of memory of size len, with tag name str. The
* name must be a static, because only a pointer to it is stored !
- * */
+ */
extern void *(*MEM_mallocN_aligned)(size_t len,
size_t alignment,
const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
diff --git a/intern/guardedalloc/intern/mmap_win.c b/intern/guardedalloc/intern/mmap_win.c
deleted file mode 100644
index a02a0f88fa9..00000000000
--- a/intern/guardedalloc/intern/mmap_win.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2008 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup MEM
- */
-
-#ifdef WIN32
-
-# include <errno.h>
-# include <io.h>
-# include <stdio.h>
-# include <sys/types.h>
-# include <windows.h>
-
-# include "mmap_win.h"
-
-# ifndef FILE_MAP_EXECUTE
-// not defined in earlier versions of the Platform SDK (before February 2003)
-# define FILE_MAP_EXECUTE 0x0020
-# endif
-
-/* copied from BLI_utildefines.h, ugh */
-# ifdef __GNUC__
-# define UNUSED(x) UNUSED_##x __attribute__((__unused__))
-# else
-# define UNUSED(x) x
-# endif
-
-/* --------------------------------------------------------------------- */
-/* local storage definitions */
-/* --------------------------------------------------------------------- */
-/* all memory mapped chunks are put in linked lists */
-typedef struct mmapLink {
- struct mmapLink *next, *prev;
-} mmapLink;
-
-typedef struct mmapListBase {
- void *first, *last;
-} mmapListBase;
-
-typedef struct MemMap {
- struct MemMap *next, *prev;
- void *mmap;
- HANDLE fhandle;
- HANDLE maphandle;
-} MemMap;
-
-/* --------------------------------------------------------------------- */
-/* local functions */
-/* --------------------------------------------------------------------- */
-
-static void mmap_addtail(volatile mmapListBase *listbase, void *vlink);
-static void mmap_remlink(volatile mmapListBase *listbase, void *vlink);
-static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr);
-
-static int mmap_get_prot_flags(int flags);
-static int mmap_get_access_flags(int flags);
-
-/* --------------------------------------------------------------------- */
-/* vars */
-/* --------------------------------------------------------------------- */
-volatile static struct mmapListBase _mmapbase;
-volatile static struct mmapListBase *mmapbase = &_mmapbase;
-
-/* --------------------------------------------------------------------- */
-/* implementation */
-/* --------------------------------------------------------------------- */
-
-/* mmap for windows */
-void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t offset)
-{
- HANDLE fhandle = INVALID_HANDLE_VALUE;
- HANDLE maphandle;
- int prot_flags = mmap_get_prot_flags(prot);
- int access_flags = mmap_get_access_flags(prot);
- MemMap *mm = NULL;
- void *ptr = NULL;
-
- if (flags & MAP_FIXED) {
- return MAP_FAILED;
- }
-
-# if 0
- if (fd == -1) {
- _set_errno(EBADF);
- return MAP_FAILED;
- }
-# endif
-
- if (fd != -1) {
- fhandle = (HANDLE)_get_osfhandle(fd);
- }
- if (fhandle == INVALID_HANDLE_VALUE) {
- if (!(flags & MAP_ANONYMOUS)) {
- errno = EBADF;
- return MAP_FAILED;
- }
- }
- else {
- if (!DuplicateHandle(GetCurrentProcess(),
- fhandle,
- GetCurrentProcess(),
- &fhandle,
- 0,
- FALSE,
- DUPLICATE_SAME_ACCESS)) {
- return MAP_FAILED;
- }
- }
-
- /* Split 64 bit size into low and high bits. */
- DWORD len_bits_high = len >> 32;
- DWORD len_bits_low = len & 0xFFFFFFFF;
-
- maphandle = CreateFileMapping(fhandle, NULL, prot_flags, len_bits_high, len_bits_low, NULL);
- if (maphandle == 0) {
- errno = EBADF;
- return MAP_FAILED;
- }
-
- ptr = MapViewOfFile(maphandle, access_flags, 0, offset, 0);
- if (ptr == NULL) {
- DWORD dwLastErr = GetLastError();
- if (dwLastErr == ERROR_MAPPED_ALIGNMENT) {
- errno = EINVAL;
- }
- else {
- errno = EACCES;
- }
- CloseHandle(maphandle);
- return MAP_FAILED;
- }
-
- mm = (MemMap *)malloc(sizeof(MemMap));
- if (!mm) {
- errno = ENOMEM;
- }
- mm->fhandle = fhandle;
- mm->maphandle = maphandle;
- mm->mmap = ptr;
- mmap_addtail(mmapbase, mm);
-
- return ptr;
-}
-
-/* munmap for windows */
-intptr_t munmap(void *ptr, size_t UNUSED(size))
-{
- MemMap *mm = mmap_findlink(mmapbase, ptr);
- if (!mm) {
- errno = EINVAL;
- return -1;
- }
- UnmapViewOfFile(mm->mmap);
- CloseHandle(mm->maphandle);
- CloseHandle(mm->fhandle);
- mmap_remlink(mmapbase, mm);
- free(mm);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/* local functions */
-/* --------------------------------------------------------------------- */
-
-static void mmap_addtail(volatile mmapListBase *listbase, void *vlink)
-{
- struct mmapLink *link = vlink;
-
- if (link == NULL) {
- return;
- }
- if (listbase == NULL) {
- return;
- }
-
- link->next = 0;
- link->prev = listbase->last;
-
- if (listbase->last) {
- ((struct mmapLink *)listbase->last)->next = link;
- }
- if (listbase->first == NULL) {
- listbase->first = link;
- }
- listbase->last = link;
-}
-
-static void mmap_remlink(volatile mmapListBase *listbase, void *vlink)
-{
- struct mmapLink *link = vlink;
-
- if (link == NULL) {
- return;
- }
- if (listbase == NULL) {
- return;
- }
- if (link->next) {
- link->next->prev = link->prev;
- }
- if (link->prev) {
- link->prev->next = link->next;
- }
-
- if (listbase->last == link) {
- listbase->last = link->prev;
- }
- if (listbase->first == link) {
- listbase->first = link->next;
- }
-}
-
-static void *mmap_findlink(volatile mmapListBase *listbase, void *ptr)
-{
- MemMap *mm;
-
- if (ptr == NULL) {
- return NULL;
- }
- if (listbase == NULL) {
- return NULL;
- }
-
- mm = (MemMap *)listbase->first;
- while (mm) {
- if (mm->mmap == ptr) {
- return mm;
- }
- mm = mm->next;
- }
- return NULL;
-}
-
-static int mmap_get_prot_flags(int flags)
-{
- int prot = PAGE_NOACCESS;
-
- if ((flags & PROT_READ) == PROT_READ) {
- if ((flags & PROT_WRITE) == PROT_WRITE) {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
- }
- else {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_READONLY;
- }
- }
- else if ((flags & PROT_WRITE) == PROT_WRITE) {
- prot = (flags & PROT_EXEC) ? PAGE_EXECUTE_READ : PAGE_WRITECOPY;
- }
- else if ((flags & PROT_EXEC) == PROT_EXEC) {
- prot = PAGE_EXECUTE_READ;
- }
- return prot;
-}
-
-static int mmap_get_access_flags(int flags)
-{
- int access = 0;
-
- if ((flags & PROT_READ) == PROT_READ) {
- if ((flags & PROT_WRITE) == PROT_WRITE) {
- access = FILE_MAP_WRITE;
- }
- else {
- access = (flags & PROT_EXEC) ? FILE_MAP_EXECUTE : FILE_MAP_READ;
- }
- }
- else if ((flags & PROT_WRITE) == PROT_WRITE) {
- access = FILE_MAP_COPY;
- }
- else if ((flags & PROT_EXEC) == PROT_EXEC) {
- access = FILE_MAP_EXECUTE;
- }
- return access;
-}
-
-#endif // WIN32
diff --git a/intern/iksolver/intern/IK_QJacobian.cpp b/intern/iksolver/intern/IK_QJacobian.cpp
index 7f77968a5d4..82aaaf7bb9a 100644
--- a/intern/iksolver/intern/IK_QJacobian.cpp
+++ b/intern/iksolver/intern/IK_QJacobian.cpp
@@ -203,7 +203,7 @@ void IK_QJacobian::InvertSDLS()
// singular the least squares inverse tries to minimize |J(dtheta) - dX)|
// and doesn't try to minimize dTheta. This results in eratic changes in
// angle. The damped least squares minimizes |dtheta| to try and reduce this
- // erratic behaviour.
+ // erratic behavior.
//
// The selectively damped least squares (SDLS) is used here instead of the
// DLS. The SDLS damps individual singular values, instead of using a single
@@ -325,7 +325,7 @@ void IK_QJacobian::InvertDLS()
// inverse tries to minimize |J(dtheta) - dX)| and doesn't
// try to minimize dTheta. This results in eratic changes in angle.
// Damped least squares minimizes |dtheta| to try and reduce this
- // erratic behaviour.
+ // erratic behavior.
// We don't want to use the damped solution everywhere so we
// only increase lamda from zero as we approach a singularity.
diff --git a/intern/libmv/libmv/numeric/numeric.h b/intern/libmv/libmv/numeric/numeric.h
index 6312b4eb1a6..f5478bee6ab 100644
--- a/intern/libmv/libmv/numeric/numeric.h
+++ b/intern/libmv/libmv/numeric/numeric.h
@@ -463,7 +463,7 @@ inline bool isnan(double i) {
#endif
}
-/// Ceil function that has the same behaviour for positive
+/// Ceil function that has the same behavior for positive
/// and negative values
template <typename FloatType>
FloatType ceil0(const FloatType& value) {
diff --git a/intern/mikktspace/mikktspace.c b/intern/mikktspace/mikktspace.c
index 17cd997f451..b0119f54019 100644
--- a/intern/mikktspace/mikktspace.c
+++ b/intern/mikktspace/mikktspace.c
@@ -138,7 +138,7 @@ MIKK_INLINE tbool VNotZero(const SVec3 v)
// Shift operations in C are only defined for shift values which are
// not negative and smaller than sizeof(value) * CHAR_BIT.
-// The mask, used with bitwise-and (&), prevents undefined behaviour
+// The mask, used with bitwise-and (&), prevents undefined behavior
// when the shift count is 0 or >= the width of unsigned int.
MIKK_INLINE unsigned int rotl(unsigned int value, unsigned int count)
{
@@ -1454,12 +1454,12 @@ static void BuildNeighborsFast(STriInfo pTriInfos[],
pEdges[f * 3 + i].f = f; // record face number
}
- // sort over all edges by i0, this is the pricy one.
+ // sort over all edges by i0, this is the pricey one.
QuickSortEdges(pEdges, 0, iNrTrianglesIn * 3 - 1, 0, uSeed); // sort channel 0 which is i0
// sub sort over i1, should be fast.
// could replace this with a 64 bit int sort over (i0,i1)
- // with i0 as msb in the quicksort call above.
+ // with i0 as msb in the quick-sort call above.
iEntries = iNrTrianglesIn * 3;
iCurStartIndex = 0;
for (i = 1; i < iEntries; i++) {
diff --git a/release/darwin/Blender.app/Contents/Info.plist b/release/darwin/Blender.app/Contents/Info.plist
index 2408cf363b1..67b786bd933 100644
--- a/release/darwin/Blender.app/Contents/Info.plist
+++ b/release/darwin/Blender.app/Contents/Info.plist
@@ -11,8 +11,6 @@
<array>
<string>blend</string>
</array>
- <key>CFBundleTypeIconFile</key>
- <string>blender file icon.icns</string>
<key>CFBundleTypeName</key>
<string>Blender File</string>
<key>CFBundleTypeOSTypes</key>
@@ -23,6 +21,12 @@
<string>Editor</string>
<key>LSIsAppleDefaultForType</key>
<true/>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>org.blenderfoundation.blender.file</string>
+ </array>
+ <key>CFBundleTypeIconSystemGenerated</key>
+ <true/>
</dict>
</array>
<key>CFBundleExecutable</key>
@@ -49,5 +53,30 @@
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<true/>
+ <key>UTExportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeIdentifier</key>
+ <string>org.blenderfoundation.blender.file</string>
+ <key>UTTypeIcons</key>
+ <dict>
+ <key>UTTypeIconName</key>
+ <string>Blender File</string>
+ <key>UTTypeIconText</key>
+ <string>blend</string>
+ </dict>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>blend</string>
+ </array>
+ </dict>
+ </dict>
+ </array>
</dict>
</plist>
diff --git a/release/darwin/Blender.app/Contents/Resources/blender file icon.icns b/release/darwin/Blender.app/Contents/Resources/blender file icon.icns
deleted file mode 100644
index 2bf78d3eb0d..00000000000
--- a/release/darwin/Blender.app/Contents/Resources/blender file icon.icns
+++ /dev/null
Binary files differ
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index 858709833fb..babb3e30c6d 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c
index b448a230da8..6383d7dfcca 100644
--- a/release/datafiles/userdef/userdef_default.c
+++ b/release/datafiles/userdef/userdef_default.c
@@ -105,7 +105,7 @@ const UserDef U_default = {
.autoexec_paths = {NULL},
.user_menus = {NULL},
- .keyconfigstr = "blender",
+ .keyconfigstr = "Blender",
.undosteps = 32,
.undomemory = 0,
.gp_manhattandist = 1,
@@ -119,6 +119,7 @@ const UserDef U_default = {
.gizmo_flag = USER_GIZMO_DRAW,
.gizmo_size = 75,
+ .gizmo_size_navigate_v3d = 80,
.edit_studio_light = 0,
.lookdev_sphere_size = 150,
.vbotimeout = 120,
diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c
index 2754b7f06f8..0477b0c9f23 100644
--- a/release/datafiles/userdef/userdef_default_theme.c
+++ b/release/datafiles/userdef/userdef_default_theme.c
@@ -489,16 +489,17 @@ const bTheme U_theme_default = {
.facedot_size = 4,
.info_selected = RGBA(0x3b5689ff),
.info_selected_text = RGBA(0xffffffff),
- .info_error = RGBA(0xff613dff),
+ .info_error = RGBA(0xb34c34ff),
.info_error_text = RGBA(0xffffffff),
- .info_warning = RGBA(0xf5bc41ff),
+ .info_warning = RGBA(0xac8737ff),
.info_warning_text = RGBA(0xffffffff),
- .info_info = RGBA(0x1d4383ff),
+ .info_info = RGBA(0x1f3862ff),
.info_info_text = RGBA(0xffffffff),
- .info_debug = RGBA(0xd3d3d3ff),
- .info_property = RGBA(0x3ace87ff),
+ .info_debug = RGBA(0x6b3293ff),
+ .info_debug_text = RGBA(0xffffffff),
+ .info_property = RGBA(0x329364ff),
.info_property_text = RGBA(0xffffffff),
- .info_operator = RGBA(0x3ace87ff),
+ .info_operator = RGBA(0x329364ff),
.info_operator_text = RGBA(0xffffffff),
},
.space_action = {
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 ebc5370a7af..ef398d5e08f 100644
--- a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
+++ b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
@@ -74,8 +74,6 @@ def generate(context, space_type, use_fallback_keys=True, use_reset=True):
if tap_reset_tool not in items_all_id:
use_tap_reset = False
- from bl_operators.wm import use_toolbar_release_hack
-
# Pie-menu style release to activate.
use_release_confirm = use_reset
@@ -437,7 +435,7 @@ def generate(context, space_type, use_fallback_keys=True, use_reset=True):
kmi = keymap.keymap_items.new(
"wm.tool_set_by_id",
- value='PRESS' if use_toolbar_release_hack else 'DOUBLE_CLICK',
+ value='DOUBLE_CLICK',
**kmi_toolbar_args_available,
)
kmi.properties.name = tap_reset_tool
@@ -451,15 +449,6 @@ def generate(context, space_type, use_fallback_keys=True, use_reset=True):
)
kmi.properties.skip_depressed = True
- if use_toolbar_release_hack:
- # ... or pass through to let the toolbar know we're released.
- # Let the operator know we're released.
- kmi = keymap.keymap_items.new(
- "wm.tool_set_by_id",
- type=kmi_toolbar_type,
- value='RELEASE',
- any=True,
- )
wm.keyconfigs.update()
return keymap
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index 3860445233d..fad52eae84a 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -201,12 +201,13 @@ _display_name_literals = {
}
-def display_name(name, *, has_ext=True):
+def display_name(name, *, has_ext=True, title_case=True):
"""
Creates a display string from name to be used menus and the user interface.
- Capitalize the first letter in all lowercase names,
- mixed case names are kept as is. Intended for use with
- filenames and module names.
+ Intended for use with filenames and module names.
+
+ :arg has_ext: Remove file extension from name
+ :arg title_case: Convert lowercase names to title case
"""
if has_ext:
@@ -220,7 +221,7 @@ def display_name(name, *, has_ext=True):
# (when paths can't start with numbers for eg).
name = name.replace("_", " ").lstrip(" ")
- if name.islower():
+ if title_case and name.islower():
name = name.lower().title()
name = _clean_utf8(name)
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 897010e80cf..7f39cc5d422 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -606,7 +606,7 @@ def preset_find(name, preset_path, display_name=False, ext=".py"):
if display_name:
filename = ""
for fn in _os.listdir(directory):
- if fn.endswith(ext) and name == _bpy.path.display_name(fn):
+ if fn.endswith(ext) and name == _bpy.path.display_name(fn, title_case=False):
filename = fn
break
else:
@@ -624,7 +624,7 @@ def keyconfig_init():
active_config = _preferences.keymap.active_keyconfig
# Load the default key configuration.
- default_filepath = preset_find("blender", "keyconfig")
+ default_filepath = preset_find("Blender", "keyconfig")
keyconfig_set(default_filepath)
# Set the active key configuration if different
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index d863778a9c2..5d89763f34b 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -982,6 +982,7 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
props_default=props_default,
filter_ext=lambda ext: ext.lower() in ext_valid,
add_operator=add_operator,
+ display_name=lambda name: bpy.path.display_name(name, title_case=False)
)
@classmethod
diff --git a/release/scripts/presets/cloth/cotton.py b/release/scripts/presets/cloth/Cotton.py
index 9e766416a75..9e766416a75 100644
--- a/release/scripts/presets/cloth/cotton.py
+++ b/release/scripts/presets/cloth/Cotton.py
diff --git a/release/scripts/presets/cloth/denim.py b/release/scripts/presets/cloth/Denim.py
index 7abf4469709..7abf4469709 100644
--- a/release/scripts/presets/cloth/denim.py
+++ b/release/scripts/presets/cloth/Denim.py
diff --git a/release/scripts/presets/cloth/leather.py b/release/scripts/presets/cloth/Leather.py
index 8ba9ff7dabe..8ba9ff7dabe 100644
--- a/release/scripts/presets/cloth/leather.py
+++ b/release/scripts/presets/cloth/Leather.py
diff --git a/release/scripts/presets/cloth/rubber.py b/release/scripts/presets/cloth/Rubber.py
index 0d791fab2a9..0d791fab2a9 100644
--- a/release/scripts/presets/cloth/rubber.py
+++ b/release/scripts/presets/cloth/Rubber.py
diff --git a/release/scripts/presets/cloth/silk.py b/release/scripts/presets/cloth/Silk.py
index af867cf9c60..af867cf9c60 100644
--- a/release/scripts/presets/cloth/silk.py
+++ b/release/scripts/presets/cloth/Silk.py
diff --git a/release/scripts/presets/cycles/integrator/direct_light.py b/release/scripts/presets/cycles/integrator/Direct_Light.py
index 701aa10d556..701aa10d556 100644
--- a/release/scripts/presets/cycles/integrator/direct_light.py
+++ b/release/scripts/presets/cycles/integrator/Direct_Light.py
diff --git a/release/scripts/presets/cycles/integrator/full_global_illumination.py b/release/scripts/presets/cycles/integrator/Full_Global_Illumination.py
index a03c6c8bd64..a03c6c8bd64 100644
--- a/release/scripts/presets/cycles/integrator/full_global_illumination.py
+++ b/release/scripts/presets/cycles/integrator/Full_Global_Illumination.py
diff --git a/release/scripts/presets/cycles/integrator/limited_global_illumination.py b/release/scripts/presets/cycles/integrator/Limited_Global_Illumination.py
index d37bf46c705..d37bf46c705 100644
--- a/release/scripts/presets/cycles/integrator/limited_global_illumination.py
+++ b/release/scripts/presets/cycles/integrator/Limited_Global_Illumination.py
diff --git a/release/scripts/presets/cycles/sampling/final.py b/release/scripts/presets/cycles/sampling/Final.py
index f1222d927c1..f1222d927c1 100644
--- a/release/scripts/presets/cycles/sampling/final.py
+++ b/release/scripts/presets/cycles/sampling/Final.py
diff --git a/release/scripts/presets/cycles/sampling/preview.py b/release/scripts/presets/cycles/sampling/Preview.py
index c16449e2c8f..c16449e2c8f 100644
--- a/release/scripts/presets/cycles/sampling/preview.py
+++ b/release/scripts/presets/cycles/sampling/Preview.py
diff --git a/release/scripts/presets/ffmpeg/h264_in_MP4.py b/release/scripts/presets/ffmpeg/H264_in_MP4.py
index 0e9c32c4878..0e9c32c4878 100644
--- a/release/scripts/presets/ffmpeg/h264_in_MP4.py
+++ b/release/scripts/presets/ffmpeg/H264_in_MP4.py
diff --git a/release/scripts/presets/ffmpeg/h264_in_Matroska.py b/release/scripts/presets/ffmpeg/H264_in_Matroska.py
index 1fe066dc4bf..1fe066dc4bf 100644
--- a/release/scripts/presets/ffmpeg/h264_in_Matroska.py
+++ b/release/scripts/presets/ffmpeg/H264_in_Matroska.py
diff --git a/release/scripts/presets/ffmpeg/h264_in_Matroska_for_scrubbing.py b/release/scripts/presets/ffmpeg/H264_in_Matroska_for_scrubbing.py
index eb1889d272f..eb1889d272f 100644
--- a/release/scripts/presets/ffmpeg/h264_in_Matroska_for_scrubbing.py
+++ b/release/scripts/presets/ffmpeg/H264_in_Matroska_for_scrubbing.py
diff --git a/release/scripts/presets/ffmpeg/ogg_theora.py b/release/scripts/presets/ffmpeg/Ogg_Theora.py
index b450b67fd98..b450b67fd98 100644
--- a/release/scripts/presets/ffmpeg/ogg_theora.py
+++ b/release/scripts/presets/ffmpeg/Ogg_Theora.py
diff --git a/release/scripts/presets/ffmpeg/xvid.py b/release/scripts/presets/ffmpeg/Xvid.py
index dba0f71c279..dba0f71c279 100644
--- a/release/scripts/presets/ffmpeg/xvid.py
+++ b/release/scripts/presets/ffmpeg/Xvid.py
diff --git a/release/scripts/presets/fluid/honey.py b/release/scripts/presets/fluid/Honey.py
index 0ed3658470a..0ed3658470a 100644
--- a/release/scripts/presets/fluid/honey.py
+++ b/release/scripts/presets/fluid/Honey.py
diff --git a/release/scripts/presets/fluid/oil.py b/release/scripts/presets/fluid/Oil.py
index c33e5d4b6cf..c33e5d4b6cf 100644
--- a/release/scripts/presets/fluid/oil.py
+++ b/release/scripts/presets/fluid/Oil.py
diff --git a/release/scripts/presets/fluid/water.py b/release/scripts/presets/fluid/Water.py
index f34ecc834ff..f34ecc834ff 100644
--- a/release/scripts/presets/fluid/water.py
+++ b/release/scripts/presets/fluid/Water.py
diff --git a/release/scripts/presets/gpencil_material/fill_only.py b/release/scripts/presets/gpencil_material/Fill_Only.py
index aa4d58a8c10..aa4d58a8c10 100644
--- a/release/scripts/presets/gpencil_material/fill_only.py
+++ b/release/scripts/presets/gpencil_material/Fill_Only.py
diff --git a/release/scripts/presets/gpencil_material/stroke_only.py b/release/scripts/presets/gpencil_material/Stroke_Only.py
index 4e02b108e01..4e02b108e01 100644
--- a/release/scripts/presets/gpencil_material/stroke_only.py
+++ b/release/scripts/presets/gpencil_material/Stroke_Only.py
diff --git a/release/scripts/presets/gpencil_material/stroke_and_fill.py b/release/scripts/presets/gpencil_material/Stroke_and_Fill.py
index 3572036de5e..3572036de5e 100644
--- a/release/scripts/presets/gpencil_material/stroke_and_fill.py
+++ b/release/scripts/presets/gpencil_material/Stroke_and_Fill.py
diff --git a/release/scripts/presets/hair_dynamics/default.py b/release/scripts/presets/hair_dynamics/Default.py
index 830d28a76f0..830d28a76f0 100644
--- a/release/scripts/presets/hair_dynamics/default.py
+++ b/release/scripts/presets/hair_dynamics/Default.py
diff --git a/release/scripts/presets/interface_theme/blender_dark.xml b/release/scripts/presets/interface_theme/Blender_Dark.xml
index 8bbb747447b..8bbb747447b 100644
--- a/release/scripts/presets/interface_theme/blender_dark.xml
+++ b/release/scripts/presets/interface_theme/Blender_Dark.xml
diff --git a/release/scripts/presets/interface_theme/blender_light.xml b/release/scripts/presets/interface_theme/Blender_Light.xml
index 91ccd574c31..77908bb6bbf 100644
--- a/release/scripts/presets/interface_theme/blender_light.xml
+++ b/release/scripts/presets/interface_theme/Blender_Light.xml
@@ -1053,19 +1053,19 @@
<info>
<ThemeInfo
info_selected="#6080ff"
- info_selected_text="#ffffff"
- info_error="#990000ff"
- info_error_text="#ffffff"
- info_warning="#b36a00ff"
- info_warning_text="#ffffff"
- info_info="#1d4383ff"
- info_info_text="#ffffff"
- info_debug="#d3d3d3ff"
+ info_selected_text="#000000"
+ info_error="#FF0038ff"
+ info_error_text="#000000"
+ info_warning="#FFE900ff"
+ info_warning_text="#000000"
+ info_info="#0068B3ff"
+ info_info_text="#000000"
+ info_debug="#B30095ff"
info_debug_text="#000000"
- info_property="#3ace87ff"
- info_property_text="#ffffff"
- info_operator="#3ace87ff"
- info_operator_text="#ffffff"
+ info_property="#44B300ff"
+ info_property_text="#000000"
+ info_operator="#44B300ff"
+ info_operator_text="#000000"
>
<space>
<ThemeSpaceGeneric
diff --git a/release/scripts/presets/keyconfig/blender.py b/release/scripts/presets/keyconfig/Blender.py
index eb66c961472..eb66c961472 100644
--- a/release/scripts/presets/keyconfig/blender.py
+++ b/release/scripts/presets/keyconfig/Blender.py
diff --git a/release/scripts/presets/keyconfig/blender_27x.py b/release/scripts/presets/keyconfig/Blender_27x.py
index efb013b9216..2a7f0b07fa6 100644
--- a/release/scripts/presets/keyconfig/blender_27x.py
+++ b/release/scripts/presets/keyconfig/Blender_27x.py
@@ -1,3 +1,28 @@
+#
+# Notes on this key-map:
+#
+# This uses Blender's key-map, running with `legacy=True`.
+#
+# The intention of this key-map is to match Blender 2.7x which had many more key-map items available.
+#
+# There are some differences with the original Blender 2.7x key-map.
+# There is no intention to change these are they are not considered significant
+# enough to make a 1:1 match with the previous Blender version.
+#
+# These include:
+#
+# 3D View
+# =======
+#
+# - Border Render (`Shift-B` -> `Ctrl-B`)
+# Both `Shift-B` and `Ctrl-B` were used.
+#
+# Time Line/Animation Views
+# =========================
+#
+# - Start Frame/End Frame (`S/E` -> `Ctrl-Home/Ctrl-End`)
+#
+
import os
import bpy
from bpy.props import (
diff --git a/release/scripts/presets/keyconfig/industry_compatible.py b/release/scripts/presets/keyconfig/Industry_Compatible.py
index 09a43452e93..09a43452e93 100644
--- a/release/scripts/presets/keyconfig/industry_compatible.py
+++ b/release/scripts/presets/keyconfig/Industry_Compatible.py
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 73f05fb3d80..fd9d699ed01 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5131,6 +5131,8 @@ def km_transform_modal_map(_params):
("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None),
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None),
+ ("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
+ ("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None),
])
return keymap
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index 4cffb6805a0..234781b7bc8 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -3962,6 +3962,8 @@ def km_transform_modal_map(_params):
("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None),
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None),
+ ("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
+ ("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None),
])
return keymap
diff --git a/release/scripts/presets/render/4k_UHDTV_2160p.py b/release/scripts/presets/render/4K_UHDTV_2160p.py
index 4517d2f435e..4517d2f435e 100644
--- a/release/scripts/presets/render/4k_UHDTV_2160p.py
+++ b/release/scripts/presets/render/4K_UHDTV_2160p.py
diff --git a/release/scripts/presets/tracking_settings/blurry_footage.py b/release/scripts/presets/tracking_settings/Blurry_Footage.py
index 253a8f395ba..253a8f395ba 100644
--- a/release/scripts/presets/tracking_settings/blurry_footage.py
+++ b/release/scripts/presets/tracking_settings/Blurry_Footage.py
diff --git a/release/scripts/presets/tracking_settings/default.py b/release/scripts/presets/tracking_settings/Default.py
index 3d2481ce7ad..3d2481ce7ad 100644
--- a/release/scripts/presets/tracking_settings/default.py
+++ b/release/scripts/presets/tracking_settings/Default.py
diff --git a/release/scripts/presets/tracking_settings/fast_motion.py b/release/scripts/presets/tracking_settings/Fast_Motion.py
index 4294b7327d1..4294b7327d1 100644
--- a/release/scripts/presets/tracking_settings/fast_motion.py
+++ b/release/scripts/presets/tracking_settings/Fast_Motion.py
diff --git a/release/scripts/presets/tracking_settings/planar.py b/release/scripts/presets/tracking_settings/Planar.py
index a099b3a800d..a099b3a800d 100644
--- a/release/scripts/presets/tracking_settings/planar.py
+++ b/release/scripts/presets/tracking_settings/Planar.py
diff --git a/release/scripts/presets/tracking_track_color/default.py b/release/scripts/presets/tracking_track_color/Default.py
index 3213d6e0c83..3213d6e0c83 100644
--- a/release/scripts/presets/tracking_track_color/default.py
+++ b/release/scripts/presets/tracking_track_color/Default.py
diff --git a/release/scripts/presets/tracking_track_color/far_plane.py b/release/scripts/presets/tracking_track_color/Far_Plane.py
index 579d5562642..579d5562642 100644
--- a/release/scripts/presets/tracking_track_color/far_plane.py
+++ b/release/scripts/presets/tracking_track_color/Far_Plane.py
diff --git a/release/scripts/presets/tracking_track_color/near_plane.py b/release/scripts/presets/tracking_track_color/Near_Plane.py
index 790429ce7a1..790429ce7a1 100644
--- a/release/scripts/presets/tracking_track_color/near_plane.py
+++ b/release/scripts/presets/tracking_track_color/Near_Plane.py
diff --git a/release/scripts/presets/tracking_track_color/object.py b/release/scripts/presets/tracking_track_color/Object.py
index 5cb663d3f97..5cb663d3f97 100644
--- a/release/scripts/presets/tracking_track_color/object.py
+++ b/release/scripts/presets/tracking_track_color/Object.py
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index 793a8648ee4..5132b358f5e 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -77,7 +77,7 @@ class AddPresetBase:
setattr(cls, attr, trans)
return trans
- name = name.lower().strip()
+ name = name.strip()
name = bpy.path.display_name_to_filepath(name)
trans = maketrans_init()
# Strip surrounding "_" as they are displayed as spaces.
@@ -249,7 +249,7 @@ class ExecutePreset(Operator):
# change the menu title to the most recently chosen option
preset_class = getattr(bpy.types, self.menu_idname)
- preset_class.bl_label = bpy.path.display_name(basename(filepath))
+ preset_class.bl_label = bpy.path.display_name(basename(filepath), title_case=False)
ext = splitext(filepath)[1].lower()
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index ee46742fbd0..2ee20e08589 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -33,11 +33,6 @@ from bpy.props import (
)
from bpy.app.translations import pgettext_iface as iface_
-# FIXME, we need a way to detect key repeat events.
-# unfortunately checking event previous values isn't reliable.
-use_toolbar_release_hack = True
-
-
rna_path_prop = StringProperty(
name="Context Attributes",
description="RNA context string",
@@ -1698,18 +1693,6 @@ class WM_OT_tool_set_by_id(Operator):
space_type: rna_space_type_prop
- if use_toolbar_release_hack:
- def invoke(self, context, event):
- # Hack :S
- if not self.properties.is_property_set("name"):
- WM_OT_toolbar._key_held = False
- return {'PASS_THROUGH'}
- elif (WM_OT_toolbar._key_held == event.type) and (event.value != 'RELEASE'):
- return {'PASS_THROUGH'}
- WM_OT_toolbar._key_held = None
-
- return self.execute(context)
-
def execute(self, context):
from bl_ui.space_toolsystem_common import (
activate_by_id,
@@ -1801,13 +1784,6 @@ class WM_OT_toolbar(Operator):
def poll(cls, context):
return context.space_data is not None
- if use_toolbar_release_hack:
- _key_held = None
-
- def invoke(self, context, event):
- WM_OT_toolbar._key_held = event.type
- return self.execute(context)
-
@staticmethod
def keymap_from_toolbar(context, space_type, use_fallback_keys=True, use_reset=True):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py
index 351d4928ddf..9db6eedb04c 100644
--- a/release/scripts/startup/bl_ui/properties_data_gpencil.py
+++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py
@@ -23,6 +23,7 @@ from rna_prop_ui import PropertyPanel
from bl_ui.properties_grease_pencil_common import (
GreasePencilLayerMasksPanel,
+ GreasePencilLayerTransformPanel,
GreasePencilLayerAdjustmentsPanel,
GreasePencilLayerRelationsPanel,
GreasePencilLayerDisplayPanel,
@@ -90,8 +91,10 @@ class GPENCIL_MT_layer_context_menu(Menu):
layout = self.layout
ob = context.object
gpd = ob.data
+ gpl = gpd.layers.active
- layout.operator("gpencil.layer_duplicate", icon='DUPLICATE')
+ layout.operator("gpencil.layer_duplicate", text="Duplicate", icon='DUPLICATE').mode='ALL'
+ layout.operator("gpencil.layer_duplicate", text="Duplicate Empty Keyframes").mode='EMPTY'
layout.separator()
@@ -103,6 +106,7 @@ class GPENCIL_MT_layer_context_menu(Menu):
layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="Unlock All")
layout.prop(gpd, "use_autolock_layers", text="Autolock Inactive Layers")
+ layout.prop(gpl, "lock_material")
layout.separator()
@@ -188,6 +192,12 @@ class DATA_PT_gpencil_layer_masks(LayerDataButtonsPanel, GreasePencilLayerMasksP
bl_options = {'DEFAULT_CLOSED'}
+class DATA_PT_gpencil_layer_transform(LayerDataButtonsPanel, GreasePencilLayerTransformPanel, Panel):
+ bl_label = "Transform"
+ bl_parent_id = 'DATA_PT_gpencil_layers'
+ bl_options = {'DEFAULT_CLOSED'}
+
+
class DATA_PT_gpencil_layer_adjustments(LayerDataButtonsPanel, GreasePencilLayerAdjustmentsPanel, Panel):
bl_label = "Adjustments"
bl_parent_id = 'DATA_PT_gpencil_layers'
@@ -424,6 +434,7 @@ classes = (
DATA_PT_gpencil_onion_skinning_custom_colors,
DATA_PT_gpencil_onion_skinning_display,
DATA_PT_gpencil_layer_masks,
+ DATA_PT_gpencil_layer_transform,
DATA_PT_gpencil_layer_adjustments,
DATA_PT_gpencil_layer_relations,
DATA_PT_gpencil_layer_display,
diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py
index d4f108dcf24..e7bf9adb876 100644
--- a/release/scripts/startup/bl_ui/properties_data_volume.py
+++ b/release/scripts/startup/bl_ui/properties_data_volume.py
@@ -63,7 +63,7 @@ class DATA_PT_volume_file(DataButtonsPanel, Panel):
layout.prop(volume, "filepath", text="")
- if len(volume.filepath):
+ if volume.filepath:
layout.use_property_split = True
layout.use_property_decorate = False
@@ -76,7 +76,7 @@ class DATA_PT_volume_file(DataButtonsPanel, Panel):
col.prop(volume, "sequence_mode", text="Mode")
error_msg = volume.grids.error_message
- if len(error_msg):
+ if error_msg:
layout.separator()
col = layout.column(align=True)
col.label(text="Failed to load volume:")
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 8b404c4a306..67905192fe8 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -727,12 +727,32 @@ class GreasePencilSimplifyPanel:
col.prop(rd, "simplify_gpencil_antialiasing")
+class GreasePencilLayerTransformPanel:
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ ob = context.object
+ gpd = ob.data
+ gpl = gpd.layers.active
+ layout.active = not gpl.lock
+
+ row = layout.row(align=True)
+ row.prop(gpl, "location")
+
+ row = layout.row(align=True)
+ row.prop(gpl, "rotation")
+
+ row = layout.row(align=True)
+ row.prop(gpl, "scale")
+
+
class GreasePencilLayerAdjustmentsPanel:
def draw(self, context):
layout = self.layout
layout.use_property_split = True
- scene = context.scene
ob = context.object
gpd = ob.data
@@ -750,15 +770,6 @@ class GreasePencilLayerAdjustmentsPanel:
col = layout.row(align=True)
col.prop(gpl, "line_change", text="Stroke Thickness")
- col = layout.row(align=True)
- col.prop(gpl, "pass_index")
-
- col = layout.row(align=True)
- col.prop_search(gpl, "viewlayer_render", scene, "view_layers", text="View Layer")
-
- col = layout.row(align=True)
- col.prop(gpl, "lock_material")
-
class GPENCIL_UL_masks(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
@@ -826,6 +837,7 @@ class GreasePencilLayerRelationsPanel:
layout.use_property_split = True
layout.use_property_decorate = False
+ scene = context.scene
ob = context.object
gpd = ob.data
gpl = gpd.layers.active
@@ -839,6 +851,14 @@ class GreasePencilLayerRelationsPanel:
if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE':
col.prop_search(gpl, "parent_bone", parent.data, "bones", text="Bone")
+ layout.separator()
+
+ col = layout.row(align=True)
+ col.prop(gpl, "pass_index")
+
+ col = layout.row(align=True)
+ col.prop_search(gpl, "viewlayer_render", scene, "view_layers", text="View Layer")
+
class GreasePencilLayerDisplayPanel:
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 5d241e8e216..54c6de30ef8 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -1218,11 +1218,11 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False)
row = layout.row(align=True)
row.prop(gp_settings, "fill_direction", text="", expand=True)
row = layout.row(align=True)
+ row.prop(gp_settings, "fill_factor")
+ row = layout.row(align=True)
row.prop(gp_settings, "fill_leak", text="Leak Size")
row = layout.row(align=True)
row.prop(brush, "size", text="Thickness")
- row = layout.row(align=True)
- row.prop(gp_settings, "fill_simplify_level", text="Simplify")
else: # brush.gpencil_tool == 'DRAW/TINT':
row = layout.row(align=True)
diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py
index c8c49ee02b0..7e017b121b3 100644
--- a/release/scripts/startup/bl_ui/properties_physics_field.py
+++ b/release/scripts/startup/bl_ui/properties_physics_field.py
@@ -118,6 +118,9 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel):
col.prop(field, "strength")
+ sub = col.column(heading="Affect")
+ sub.prop(field, "apply_to_location", text="Location")
+
col = flow.column()
col.prop(field, "texture_nabla")
col.prop(field, "use_object_coords")
@@ -128,6 +131,10 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel):
col.prop(field, "strength")
col.prop(field, "flow")
+ sub = col.column(heading="Affect")
+ sub.prop(field, "apply_to_location", text="Location")
+ sub.prop(field, "apply_to_rotation", text="Rotation")
+
col = flow.column()
col.prop(field, "source_object")
col.prop(field, "use_smoke_density")
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 9d74a9c9fea..96920af1c7e 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -502,7 +502,9 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
col = layout.column(align=True)
row = col.row(align=True)
row.label(text="Merge:")
- row.operator("clip.join_tracks", text="Join Tracks")
+ sub = row.column()
+ sub.operator("clip.join_tracks", text="Join Tracks")
+ sub.operator("clip.average_tracks", text="Average Tracks")
class CLIP_PT_tools_plane_tracking(CLIP_PT_tracking_panel, Panel):
@@ -1482,6 +1484,7 @@ class CLIP_MT_track(Menu):
layout.separator()
layout.operator("clip.join_tracks")
+ layout.operator("clip.average_tracks")
layout.separator()
@@ -1608,6 +1611,7 @@ class CLIP_MT_tracking_context_menu(Menu):
layout.separator()
layout.operator("clip.join_tracks")
+ layout.operator("clip.average_tracks")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 0c222e8c023..aa98e4292f4 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -27,6 +27,7 @@ from bpy.types import (
from bl_ui.properties_grease_pencil_common import (
GreasePencilLayerMasksPanel,
+ GreasePencilLayerTransformPanel,
GreasePencilLayerAdjustmentsPanel,
GreasePencilLayerRelationsPanel,
GreasePencilLayerDisplayPanel,
@@ -726,6 +727,12 @@ class DOPESHEET_PT_gpencil_layer_masks(LayersDopeSheetPanel, GreasePencilLayerMa
bl_options = {'DEFAULT_CLOSED'}
+class DOPESHEET_PT_gpencil_layer_transform(LayersDopeSheetPanel, GreasePencilLayerTransformPanel, Panel):
+ bl_label = "Transform"
+ bl_parent_id = 'DOPESHEET_PT_gpencil_mode'
+ bl_options = {'DEFAULT_CLOSED'}
+
+
class DOPESHEET_PT_gpencil_layer_adjustments(LayersDopeSheetPanel, GreasePencilLayerAdjustmentsPanel, Panel):
bl_label = "Adjustments"
bl_parent_id = 'DOPESHEET_PT_gpencil_mode'
@@ -762,6 +769,7 @@ classes = (
DOPESHEET_PT_filters,
DOPESHEET_PT_gpencil_mode,
DOPESHEET_PT_gpencil_layer_masks,
+ DOPESHEET_PT_gpencil_layer_transform,
DOPESHEET_PT_gpencil_layer_adjustments,
DOPESHEET_PT_gpencil_layer_relations,
DOPESHEET_PT_gpencil_layer_display,
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 342b72acb8c..73cc674858c 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -235,6 +235,7 @@ class IMAGE_MT_image(Menu):
layout.menu("IMAGE_MT_image_invert")
layout.operator("image.resize", text="Resize")
+ layout.menu("IMAGE_MT_image_flip")
if ima and not show_render:
if ima.packed_file:
@@ -250,6 +251,13 @@ class IMAGE_MT_image(Menu):
layout.operator("palette.extract_from_image", text="Extract Palette")
layout.operator("gpencil.image_to_grease_pencil", text="Generate Grease Pencil")
+class IMAGE_MT_image_flip(Menu):
+ bl_label = "Flip"
+
+ def draw(self, _context):
+ layout = self.layout
+ layout.operator("image.flip", text="Horizontally").use_flip_horizontal = True
+ layout.operator("image.flip", text="Vertically").use_flip_vertical = True
class IMAGE_MT_image_invert(Menu):
bl_label = "Invert"
@@ -1584,6 +1592,7 @@ classes = (
IMAGE_MT_select,
IMAGE_MT_select_linked,
IMAGE_MT_image,
+ IMAGE_MT_image_flip,
IMAGE_MT_image_invert,
IMAGE_MT_uvs,
IMAGE_MT_uvs_showhide,
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index e6af83b61f4..a9934850acd 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -678,16 +678,8 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
- # inputs get icon on the left
- if not socket.is_output:
- row.template_node_socket(color=color)
-
+ row.template_node_socket(color=color)
row.prop(socket, "name", text="", emboss=False, icon_value=icon)
-
- # outputs get icon on the right
- if socket.is_output:
- row.template_node_socket(color=color)
-
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.template_node_socket(color=color)
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 4b30266a5fe..a0b5355e64d 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -691,6 +691,9 @@ class USERPREF_PT_viewport_display(ViewportPanel, CenterAlignMixIn, Panel):
col.prop(view, "mini_axis_size", text="Size")
col.prop(view, "mini_axis_brightness", text="Brightness")
+ if view.mini_axis_type == 'GIZMO':
+ col.prop(view, "gizmo_size_navigate_v3d", text="Size")
+
class USERPREF_PT_viewport_quality(ViewportPanel, CenterAlignMixIn, Panel):
bl_label = "Quality"
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index b9a57674a6e..0fe16720d81 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -695,6 +695,10 @@ class VIEW3D_HT_header(Header):
row.prop(tool_settings, "use_gpencil_vertex_select_mask_stroke", text="")
row.prop(tool_settings, "use_gpencil_vertex_select_mask_segment", text="")
+ if gpd.is_stroke_paint_mode:
+ row = layout.row(align=True)
+ row.prop(gpd, "use_multiedit", text="", icon='GP_MULTIFRAME_EDITING')
+
if (
gpd.use_stroke_edit_mode or
gpd.is_stroke_sculpt_mode or
@@ -2236,11 +2240,6 @@ class VIEW3D_MT_object_relations(Menu):
layout.operator_menu_enum("object.make_local", "type", text="Make Local...")
layout.menu("VIEW3D_MT_make_single_user")
- layout.separator()
-
- layout.operator("object.data_transfer")
- layout.operator("object.datalayout_transfer")
-
class VIEW3D_MT_object(Menu):
bl_context = "objectmode"
@@ -2274,7 +2273,7 @@ class VIEW3D_MT_object(Menu):
layout.menu("VIEW3D_MT_object_relations")
layout.menu("VIEW3D_MT_object_constraints")
layout.menu("VIEW3D_MT_object_track")
- layout.menu("VIEW3D_MT_make_links", text="Make Links")
+ layout.menu("VIEW3D_MT_make_links")
layout.separator()
@@ -2292,16 +2291,7 @@ class VIEW3D_MT_object(Menu):
layout.separator()
- ob = context.active_object
- if ob and ob.type == 'GPENCIL' and context.gpencil_data:
- layout.operator_menu_enum("gpencil.convert", "type", text="Convert To")
- else:
- layout.operator_menu_enum("object.convert", "target")
-
- # Potrace lib dependency
- if bpy.app.build_options.potrace:
- layout.separator()
- layout.operator("gpencil.trace_image")
+ layout.menu("VIEW3D_MT_object_convert")
layout.separator()
@@ -2397,37 +2387,25 @@ class VIEW3D_MT_object_context_menu(Menu):
'''
# If something is selected
- if obj is not None and obj.type in {'MESH', 'CURVE', 'SURFACE'}:
- layout.operator("object.shade_smooth", text="Shade Smooth")
- layout.operator("object.shade_flat", text="Shade Flat")
-
- layout.separator()
+ # Individual object types.
if obj is None:
pass
- elif obj.type == 'MESH':
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
-
- layout.operator_context = 'INVOKE_DEFAULT'
- # If more than one object is selected
- if selected_objects_len > 1:
- layout.operator("object.join")
-
- layout.separator()
elif obj.type == 'CAMERA':
layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("view3d.object_as_camera", text="Set Active Camera")
+
if obj.data.type == 'PERSP':
- props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Focal Length")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.lens"
props.input_scale = 0.1
if obj.data.lens_unit == 'MILLIMETERS':
- props.header_text = "Camera Lens Angle: %.1fmm"
+ props.header_text = "Camera Focal Length: %.1fmm"
else:
- props.header_text = "Camera Lens Angle: %.1f\u00B0"
+ props.header_text = "Camera Focal Length: %.1f\u00B0"
else:
props = layout.operator("wm.context_modal_mouse", text="Camera Lens Scale")
@@ -2440,88 +2418,83 @@ class VIEW3D_MT_object_context_menu(Menu):
if view and view.camera == obj and view.region_3d.view_perspective == 'CAMERA':
props = layout.operator("ui.eyedropper_depth", text="DOF Distance (Pick)")
else:
- props = layout.operator("wm.context_modal_mouse", text="DOF Distance")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Focus Distance")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.dof.focus_distance"
props.input_scale = 0.02
- props.header_text = "DOF Distance: %.3f"
+ props.header_text = "Focus Distance: %.3f"
layout.separator()
elif obj.type in {'CURVE', 'FONT'}:
layout.operator_context = 'INVOKE_REGION_WIN'
- props = layout.operator("wm.context_modal_mouse", text="Extrude Size")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Extrusion")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.extrude"
props.input_scale = 0.01
- props.header_text = "Extrude Size: %.3f"
+ props.header_text = "Extrude: %.3f"
- props = layout.operator("wm.context_modal_mouse", text="Width Size")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Offset")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.offset"
props.input_scale = 0.01
- props.header_text = "Width Size: %.3f"
-
- layout.separator()
-
- layout.operator("object.convert", text="Convert to Mesh").target = 'MESH'
- layout.operator("object.convert", text="Convert to Grease Pencil").target = 'GPENCIL'
- layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
-
- layout.separator()
-
- elif obj.type == 'GPENCIL':
- layout.operator("gpencil.convert", text="Convert to Path").type = 'PATH'
- layout.operator("gpencil.convert", text="Convert to Bezier Curve").type = 'CURVE'
- layout.operator("gpencil.convert", text="Convert to Polygon Curve").type = 'POLY'
-
- layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
+ props.header_text = "Offset: %.3f"
layout.separator()
elif obj.type == 'EMPTY':
layout.operator_context = 'INVOKE_REGION_WIN'
- props = layout.operator("wm.context_modal_mouse", text="Empty Draw Size")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Empty Display Size")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "empty_display_size"
props.input_scale = 0.01
- props.header_text = "Empty Draw Size: %.3f"
+ props.header_text = "Empty Display Size: %.3f"
layout.separator()
+ if obj.empty_display_type == 'IMAGE':
+ layout.operator("gpencil.trace_image")
+
+ layout.separator()
+
elif obj.type == 'LIGHT':
light = obj.data
layout.operator_context = 'INVOKE_REGION_WIN'
- props = layout.operator("wm.context_modal_mouse", text="Power")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Light Power")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.energy"
props.input_scale = 1.0
props.header_text = "Light Power: %.3f"
if light.type == 'AREA':
- props = layout.operator("wm.context_modal_mouse", text="Size X")
- props.data_path_iter = "selected_editable_objects"
- props.data_path_item = "data.size"
- props.header_text = "Light Size X: %.3f"
-
if light.shape in {'RECTANGLE', 'ELLIPSE'}:
- props = layout.operator("wm.context_modal_mouse", text="Size Y")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Area Light X Size")
+ props.data_path_iter = "selected_editable_objects"
+ props.data_path_item = "data.size"
+ props.header_text = "Light Size X: %.3f"
+
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Area Light Y Size")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.size_y"
props.header_text = "Light Size Y: %.3f"
+ else:
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Area Light Size")
+ props.data_path_iter = "selected_editable_objects"
+ props.data_path_item = "data.size"
+ props.header_text = "Light Size: %.3f"
elif light.type in {'SPOT', 'POINT'}:
- props = layout.operator("wm.context_modal_mouse", text="Radius")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Light Radius")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.shadow_soft_size"
props.header_text = "Light Radius: %.3f"
elif light.type == 'SUN':
- props = layout.operator("wm.context_modal_mouse", text="Angle")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Sun Light Angle")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.angle"
props.header_text = "Light Angle: %.3f"
@@ -2529,13 +2502,13 @@ class VIEW3D_MT_object_context_menu(Menu):
if light.type == 'SPOT':
layout.separator()
- props = layout.operator("wm.context_modal_mouse", text="Spot Size")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Spot Light Size")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.spot_size"
props.input_scale = 0.01
props.header_text = "Spot Size: %.2f"
- props = layout.operator("wm.context_modal_mouse", text="Spot Blend")
+ props = layout.operator("wm.context_modal_mouse", text="Adjust Spot Light Blend")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.spot_blend"
props.input_scale = -0.01
@@ -2543,6 +2516,35 @@ class VIEW3D_MT_object_context_menu(Menu):
layout.separator()
+ # Shared among some object types.
+ if obj is not None:
+ if obj.type in {'MESH', 'CURVE', 'SURFACE'}:
+ layout.operator("object.shade_smooth", text="Shade Smooth")
+ layout.operator("object.shade_flat", text="Shade Flat")
+
+ layout.separator()
+
+ if obj.type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE', 'GPENCIL'}:
+ if selected_objects_len > 1:
+ layout.operator("object.join")
+
+ if obj.type in {'MESH', 'CURVE', 'SURFACE', 'POINTCLOUD', 'META', 'FONT'}:
+ layout.operator_menu_enum("object.convert", "target")
+
+ if obj.type == 'GPENCIL':
+ layout.operator_menu_enum("gpencil.convert", "type", text="Convert To")
+
+ if (
+ obj.type in {'MESH', 'CURVE', 'SURFACE', 'GPENCIL', 'LATTICE', 'ARMATURE', 'META'} or
+ (obj.type == 'EMPTY' and obj.instance_collection is not None)
+ ):
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
+ layout.operator_context = 'INVOKE_DEFAULT'
+
+ layout.separator()
+
+ # Shared among all object types
layout.operator("view3d.copybuffer", text="Copy Objects", icon='COPYDOWN')
layout.operator("view3d.pastebuffer", text="Paste Objects", icon='PASTEDOWN')
@@ -2787,8 +2789,25 @@ class VIEW3D_MT_make_single_user(Menu):
props.object = props.obdata = props.material = False
+class VIEW3D_MT_object_convert(Menu):
+ bl_label = "Convert"
+
+ def draw(self, context):
+ layout = self.layout
+ ob = context.active_object
+
+ if ob and ob.type == 'GPENCIL' and context.gpencil_data:
+ layout.operator_enum("gpencil.convert", "type")
+ else:
+ layout.operator_enum("object.convert", "target")
+
+ # Potrace lib dependency.
+ if bpy.app.build_options.potrace:
+ layout.operator("gpencil.trace_image", icon='OUTLINER_OB_GREASEPENCIL')
+
+
class VIEW3D_MT_make_links(Menu):
- bl_label = "Make Links"
+ bl_label = "Link/Transfer Data"
def draw(self, _context):
layout = self.layout
@@ -2796,10 +2815,10 @@ class VIEW3D_MT_make_links(Menu):
if len(bpy.data.scenes) > 10:
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("object.make_links_scene", text="Objects to Scene...", icon='OUTLINER_OB_EMPTY')
+ layout.operator("object.make_links_scene", text="Link Objects to Scene...", icon='OUTLINER_OB_EMPTY')
else:
layout.operator_context = 'EXEC_REGION_WIN'
- layout.operator_menu_enum("object.make_links_scene", "scene", text="Objects to Scene")
+ layout.operator_menu_enum("object.make_links_scene", "scene", text="Link Objects to Scene")
layout.separator()
@@ -2807,7 +2826,12 @@ class VIEW3D_MT_make_links(Menu):
layout.operator_enum("object.make_links_data", "type") # inline
- layout.operator("object.join_uvs") # stupid place to add this!
+ layout.operator("object.join_uvs", text="Copy UV Maps")
+
+ layout.separator()
+
+ layout.operator("object.data_transfer")
+ layout.operator("object.datalayout_transfer")
class VIEW3D_MT_brush_paint_modes(Menu):
@@ -7529,6 +7553,7 @@ classes = (
VIEW3D_MT_object_rigid_body,
VIEW3D_MT_object_clear,
VIEW3D_MT_object_context_menu,
+ VIEW3D_MT_object_convert,
VIEW3D_MT_object_shading,
VIEW3D_MT_object_apply,
VIEW3D_MT_object_relations,
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 577f9678a62..f93a6f3346b 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -352,10 +352,13 @@ class VIEW3D_PT_tools_particlemode(Panel, View3DPaintPanel):
layout.row().prop(brush, "puff_mode", expand=True)
layout.prop(brush, "use_puff_volume")
elif tool == 'COMB':
- layout.prop(settings, "use_emitter_deflect", text="Deflect Emitter")
- col = layout.column()
- col.active = settings.use_emitter_deflect
- col.prop(settings, "emitter_distance", text="Distance")
+ col = layout.column(align=False, heading="Deflect Emitter")
+ row = col.row(align=True)
+ sub = row.row(align=True)
+ sub.prop(settings, "use_emitter_deflect", text="")
+ sub = sub.row(align=True)
+ sub.active = settings.use_emitter_deflect
+ sub.prop(settings, "emitter_distance", text="")
# TODO, move to space_view3d.py
@@ -1231,14 +1234,20 @@ class VIEW3D_PT_tools_particlemode_options(View3DPanel, Panel):
col = layout.column(align=True)
col.active = pe.is_editable
- col.prop(ob.data, "use_mirror_x")
- if pe.tool == 'ADD':
- col.prop(ob.data, "use_mirror_topology")
- col.separator()
- col.prop(pe, "use_preserve_length", text="Preserve Strand Lengths")
- col.prop(pe, "use_preserve_root", text="Preserve Root Positions")
+
if not pe.is_hair:
col.prop(pe, "use_auto_velocity", text="Auto-Velocity")
+ col.separator()
+
+ sub = col.column(align=True, heading="Mirror")
+ sub.prop(ob.data, "use_mirror_x")
+ if pe.tool == 'ADD':
+ sub.prop(ob.data, "use_mirror_topology")
+ col.separator()
+
+ sub = col.column(align=True, heading="Preserve")
+ sub.prop(pe, "use_preserve_length", text="Strand Lengths")
+ sub.prop(pe, "use_preserve_root", text="Root Positions")
class VIEW3D_PT_tools_particlemode_options_shapecut(View3DPanel, Panel):
@@ -1282,10 +1291,13 @@ class VIEW3D_PT_tools_particlemode_options_display(View3DPanel, Panel):
else:
if pe.type == 'PARTICLES':
col.prop(pe, "show_particles", text="Particles")
- col.prop(pe, "use_fade_time")
- sub = col.row(align=True)
+ col = layout.column(align=False, heading="Fade Time")
+ row = col.row(align=True)
+ sub = row.row(align=True)
+ sub.prop(pe, "use_fade_time", text="")
+ sub = sub.row(align=True)
sub.active = pe.use_fade_time
- sub.prop(pe, "fade_frames", slider=True)
+ sub.prop(pe, "fade_frames", slider=True, text="")
# ********** grease pencil object tool panels ****************
@@ -1382,7 +1394,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_settings'
bl_category = "Tool"
bl_options = {'DEFAULT_CLOSED'}
- bl_ui_units_x = 11
+ bl_ui_units_x = 13
@classmethod
def poll(cls, context):
@@ -1435,7 +1447,12 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
row.prop(gp_settings, "fill_layer_mode", text="Layers")
col.separator()
- col.prop(gp_settings, "fill_factor", text="Resolution")
+ row = col.row(align=True)
+ row.prop(gp_settings, "extend_stroke_factor")
+ row.prop(gp_settings, "show_fill_extend", text="", icon='GRID')
+
+ 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")
col.use_property_decorate = False
@@ -1446,6 +1463,10 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
sub.active = gp_settings.show_fill
sub.prop(gp_settings, "fill_threshold", text="")
+ col.separator()
+ row = col.row(align=True)
+ row.prop(gp_settings, "use_fill_limit")
+
class VIEW3D_PT_tools_grease_pencil_brush_stroke(Panel, View3DPanel):
bl_context = ".greasepencil_paint"
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 7abc62a69e3..9d7485a0837 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -487,8 +487,12 @@ geometry_node_categories = [
NodeItem("GeometryNodeAttributeCompare"),
NodeItem("GeometryNodeAttributeFill"),
NodeItem("GeometryNodeAttributeMix"),
+ NodeItem("GeometryNodeAttributeProximity"),
NodeItem("GeometryNodeAttributeColorRamp"),
NodeItem("GeometryNodeAttributeVectorMath"),
+ NodeItem("GeometryNodeAttributeSampleTexture"),
+ NodeItem("GeometryNodeAttributeCombineXYZ"),
+ NodeItem("GeometryNodeAttributeSeparateXYZ"),
]),
GeometryNodeCategory("GEO_COLOR", "Color", items=[
NodeItem("ShaderNodeValToRGB"),
@@ -501,9 +505,11 @@ geometry_node_categories = [
]),
GeometryNodeCategory("GEO_INPUT", "Input", items=[
NodeItem("GeometryNodeObjectInfo"),
+ NodeItem("GeometryNodeCollectionInfo"),
NodeItem("FunctionNodeRandomFloat"),
NodeItem("ShaderNodeValue"),
NodeItem("FunctionNodeInputVector"),
+ NodeItem("GeometryNodeIsViewport"),
]),
GeometryNodeCategory("GEO_MESH", "Mesh", items=[
NodeItem("GeometryNodeBoolean"),
@@ -520,6 +526,10 @@ geometry_node_categories = [
NodeItem("GeometryNodeRotatePoints"),
NodeItem("GeometryNodeAlignRotationToVector"),
]),
+ GeometryNodeCategory("GEO_VOLUME", "Volume", items=[
+ NodeItem("GeometryNodePointsToVolume"),
+ NodeItem("GeometryNodeVolumeToMesh"),
+ ]),
GeometryNodeCategory("GEO_UTILITIES", "Utilities", items=[
NodeItem("ShaderNodeMapRange"),
NodeItem("ShaderNodeClamp"),
diff --git a/release/windows/batch/blender_debug_gpu.cmd b/release/windows/batch/blender_debug_gpu.cmd
index 46d126ab621..53d7863ec70 100644
--- a/release/windows/batch/blender_debug_gpu.cmd
+++ b/release/windows/batch/blender_debug_gpu.cmd
@@ -12,5 +12,5 @@ mkdir "%temp%\blender\debug_logs" > NUL 2>&1
echo.
echo Starting blender and waiting for it to exit....
set PYTHONPATH=
-"%~dp0\blender" --debug --debug-gpu --python-expr "import bpy; bpy.ops.wm.sysinfo(filepath=r'%temp%\blender\debug_logs\blender_system_info.txt')" > "%temp%\blender\debug_logs\blender_debug_output.txt" 2>&1 < %0
+"%~dp0\blender" --debug --debug-gpu --debug-cycles --python-expr "import bpy; bpy.ops.wm.sysinfo(filepath=r'%temp%\blender\debug_logs\blender_system_info.txt')" > "%temp%\blender\debug_logs\blender_debug_output.txt" 2>&1 < %0
explorer "%temp%\blender\debug_logs" \ No newline at end of file
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index efd30ba8509..f875a990d0a 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -20,6 +20,7 @@
set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ID.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ID_enums.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_action_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_anim_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_armature_types.h
diff --git a/source/blender/blendthumb/src/Dll.cpp b/source/blender/blendthumb/src/Dll.cpp
index 8a8ae8c9996..6516540034e 100644
--- a/source/blender/blendthumb/src/Dll.cpp
+++ b/source/blender/blendthumb/src/Dll.cpp
@@ -160,7 +160,7 @@ struct REGISTRY_ENTRY {
PCWSTR pszValueName;
DWORD dwValueType;
PCWSTR pszData; // These two fields could/should have been a union, but C++
- DWORD dwData; // only lets you initalize the first field in a union.
+ DWORD dwData; // only lets you initialize the first field in a union.
};
// Creates a registry key (if needed) and sets the default value of the key
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 8d904bd6019..2fce4bfc5b8 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -212,8 +212,7 @@ struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
struct ListBase *cache,
struct PointerRNA *ptr,
struct AnimData *adt,
- const struct AnimationEvalContext *anim_eval_context,
- const bool flush_to_original);
+ const struct AnimationEvalContext *anim_eval_context);
bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
struct PointerRNA *prop_ptr,
struct PropertyRNA *prop,
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index abcf8ed1c54..55c8b36669d 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -24,6 +24,7 @@
#include "BKE_attribute.h"
#include "BLI_color.hh"
+#include "BLI_float2.hh"
#include "BLI_float3.hh"
namespace blender::bke {
@@ -127,7 +128,7 @@ class WriteAttribute {
void *array_buffer_ = nullptr;
/* True, when the buffer points to a temporary array. */
bool array_is_temporary_ = false;
- /* This helps to protect agains forgetting to apply changes done to the array. */
+ /* This helps to protect against forgetting to apply changes done to the array. */
bool array_should_be_applied_ = false;
public:
@@ -301,11 +302,13 @@ template<typename T> class TypedWriteAttribute {
using BooleanReadAttribute = TypedReadAttribute<bool>;
using FloatReadAttribute = TypedReadAttribute<float>;
+using Float2ReadAttribute = TypedReadAttribute<float2>;
using Float3ReadAttribute = TypedReadAttribute<float3>;
using Int32ReadAttribute = TypedReadAttribute<int>;
using Color4fReadAttribute = TypedReadAttribute<Color4f>;
using BooleanWriteAttribute = TypedWriteAttribute<bool>;
using FloatWriteAttribute = TypedWriteAttribute<float>;
+using Float2WriteAttribute = TypedWriteAttribute<float2>;
using Float3WriteAttribute = TypedWriteAttribute<float3>;
using Int32WriteAttribute = TypedWriteAttribute<int>;
using Color4fWriteAttribute = TypedWriteAttribute<Color4f>;
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
new file mode 100644
index 00000000000..0294a8c09d5
--- /dev/null
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -0,0 +1,256 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_array.hh"
+#include "BLI_color.hh"
+#include "BLI_float2.hh"
+#include "BLI_float3.hh"
+
+#include "DNA_customdata_types.h"
+
+namespace blender::attribute_math {
+
+/**
+ * Utility function that simplifies calling a templated function based on a custom data type.
+ */
+template<typename Func>
+void convert_to_static_type(const CustomDataType data_type, const Func &func)
+{
+ switch (data_type) {
+ case CD_PROP_FLOAT:
+ func(float());
+ break;
+ case CD_PROP_FLOAT2:
+ func(float2());
+ break;
+ case CD_PROP_FLOAT3:
+ func(float3());
+ break;
+ case CD_PROP_INT32:
+ func(int());
+ break;
+ case CD_PROP_BOOL:
+ func(bool());
+ break;
+ case CD_PROP_COLOR:
+ func(Color4f());
+ break;
+ default:
+ BLI_assert(false);
+ break;
+ }
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Mix three values of the same type.
+ *
+ * This is typically used to interpolate values within a triangle.
+ * \{ */
+
+template<typename T> T mix3(const float3 &weights, const T &v0, const T &v1, const T &v2);
+
+template<> inline bool mix3(const float3 &weights, const bool &v0, const bool &v1, const bool &v2)
+{
+ return (weights.x * v0 + weights.y * v1 + weights.z * v2) >= 0.5f;
+}
+
+template<> inline int mix3(const float3 &weights, const int &v0, const int &v1, const int &v2)
+{
+ return static_cast<int>(weights.x * v0 + weights.y * v1 + weights.z * v2);
+}
+
+template<>
+inline float mix3(const float3 &weights, const float &v0, const float &v1, const float &v2)
+{
+ return weights.x * v0 + weights.y * v1 + weights.z * v2;
+}
+
+template<>
+inline float2 mix3(const float3 &weights, const float2 &v0, const float2 &v1, const float2 &v2)
+{
+ return weights.x * v0 + weights.y * v1 + weights.z * v2;
+}
+
+template<>
+inline float3 mix3(const float3 &weights, const float3 &v0, const float3 &v1, const float3 &v2)
+{
+ return weights.x * v0 + weights.y * v1 + weights.z * v2;
+}
+
+template<>
+inline Color4f mix3(const float3 &weights, const Color4f &v0, const Color4f &v1, const Color4f &v2)
+{
+ Color4f result;
+ interp_v4_v4v4v4(result, v0, v1, v2, weights);
+ return result;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Mix a dynamic amount of values with weights for many elements.
+ *
+ * This section provides an abstraction for "mixers". The abstraction encapsulates details about
+ * how different types should be mixed. Usually #DefaultMixer<T> should be used to get a mixer for
+ * a specific type.
+ * \{ */
+
+template<typename T> class SimpleMixer {
+ private:
+ MutableSpan<T> buffer_;
+ T default_value_;
+ Array<float> total_weights_;
+
+ public:
+ /**
+ * \param buffer: Span where the interpolated values should be stored.
+ * \param default_value: Output value for an element that has not been affected by a #mix_in.
+ */
+ SimpleMixer(MutableSpan<T> buffer, T default_value = {})
+ : buffer_(buffer), default_value_(default_value), total_weights_(buffer.size(), 0.0f)
+ {
+ BLI_STATIC_ASSERT(std::is_trivial_v<T>, "");
+ memset(buffer_.data(), 0, sizeof(T) * buffer_.size());
+ }
+
+ /**
+ * Mix a #value into the element with the given #index.
+ */
+ void mix_in(const int64_t index, const T &value, const float weight = 1.0f)
+ {
+ BLI_assert(weight >= 0.0f);
+ buffer_[index] += value * weight;
+ total_weights_[index] += weight;
+ }
+
+ /**
+ * Has to be called before the buffer provided in the constructor is used.
+ */
+ void finalize()
+ {
+ for (const int64_t i : buffer_.index_range()) {
+ const float weight = total_weights_[i];
+ if (weight > 0.0f) {
+ buffer_[i] *= 1.0f / weight;
+ }
+ else {
+ buffer_[i] = default_value_;
+ }
+ }
+ }
+};
+
+/** This mixer accumulates values in a type that is different from the one that is mixed. Some
+ * types cannot encode the floating point weights in their values (e.g. int and bool). */
+template<typename T, typename AccumulationT, T (*ConvertToT)(const AccumulationT &value)>
+class SimpleMixerWithAccumulationType {
+ private:
+ struct Item {
+ /* Store both values together, because they are accessed together. */
+ AccumulationT value = {0};
+ float weight = 0.0f;
+ };
+
+ MutableSpan<T> buffer_;
+ T default_value_;
+ Array<Item> accumulation_buffer_;
+
+ public:
+ SimpleMixerWithAccumulationType(MutableSpan<T> buffer, T default_value = {})
+ : buffer_(buffer), default_value_(default_value), accumulation_buffer_(buffer.size())
+ {
+ }
+
+ void mix_in(const int64_t index, const T &value, const float weight = 1.0f)
+ {
+ const AccumulationT converted_value = static_cast<AccumulationT>(value);
+ Item &item = accumulation_buffer_[index];
+ item.value += converted_value * weight;
+ item.weight += weight;
+ }
+
+ void finalize()
+ {
+ for (const int64_t i : buffer_.index_range()) {
+ const Item &item = accumulation_buffer_[i];
+ if (item.weight > 0.0f) {
+ const float weight_inv = 1.0f / item.weight;
+ const T converted_value = ConvertToT(item.value * weight_inv);
+ buffer_[i] = converted_value;
+ }
+ else {
+ buffer_[i] = default_value_;
+ }
+ }
+ }
+};
+
+class Color4fMixer {
+ private:
+ MutableSpan<Color4f> buffer_;
+ Color4f default_color_;
+ Array<float> total_weights_;
+
+ public:
+ Color4fMixer(MutableSpan<Color4f> buffer, Color4f default_color = {0, 0, 0, 1});
+ void mix_in(const int64_t index, const Color4f &color, const float weight = 1.0f);
+ void finalize();
+};
+
+template<typename T> struct DefaultMixerStruct {
+ /* Use void by default. This can be check for in `if constexpr` statements. */
+ using type = void;
+};
+template<> struct DefaultMixerStruct<float> {
+ using type = SimpleMixer<float>;
+};
+template<> struct DefaultMixerStruct<float2> {
+ using type = SimpleMixer<float2>;
+};
+template<> struct DefaultMixerStruct<float3> {
+ using type = SimpleMixer<float3>;
+};
+template<> struct DefaultMixerStruct<Color4f> {
+ /* Use a special mixer for colors. Color4f can't be added/multiplied, because this is not
+ * something one should usually do with colors. */
+ using type = Color4fMixer;
+};
+template<> struct DefaultMixerStruct<int> {
+ static int double_to_int(const double &value)
+ {
+ return static_cast<int>(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. */
+ using type = SimpleMixerWithAccumulationType<int, double, double_to_int>;
+};
+template<> struct DefaultMixerStruct<bool> {
+ static bool float_to_bool(const float &value)
+ {
+ return value >= 0.5f;
+ }
+ /* Store interpolated booleans in a float temporary.
+ * Otherwise information provided by weights is easily rounded away. */
+ using type = SimpleMixerWithAccumulationType<bool, float, float_to_bool>;
+};
+
+/* Utility to get a good default mixer for a given type. This is `void` when there is no default
+ * mixer for the given type. */
+template<typename T> using DefaultMixer = typename DefaultMixerStruct<T>::type;
+
+/** \} */
+
+} // namespace blender::attribute_math
diff --git a/source/blender/blenkernel/BKE_blender_undo.h b/source/blender/blenkernel/BKE_blender_undo.h
index e5ce91df3fb..1febe75b6f2 100644
--- a/source/blender/blenkernel/BKE_blender_undo.h
+++ b/source/blender/blenkernel/BKE_blender_undo.h
@@ -27,12 +27,14 @@ struct Main;
struct MemFileUndoData;
struct bContext;
+enum eUndoStepDir;
+
#define BKE_UNDO_STR_MAX 64
struct MemFileUndoData *BKE_memfile_undo_encode(struct Main *bmain,
struct MemFileUndoData *mfu_prev);
bool BKE_memfile_undo_decode(struct MemFileUndoData *mfu,
- const int undo_direction,
+ const enum eUndoStepDir undo_direction,
const bool use_old_bmain_data,
struct bContext *C);
void BKE_memfile_undo_free(struct MemFileUndoData *mfu);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 4ee96d1ab8d..c6fe02202a6 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -31,15 +31,15 @@ extern "C" {
*/
/* Blender major and minor version. */
-#define BLENDER_VERSION 292
+#define BLENDER_VERSION 293
/* Blender patch version for bugfix releases. */
#define BLENDER_VERSION_PATCH 0
/** Blender release cycle stage: alpha/beta/rc/release. */
-#define BLENDER_VERSION_CYCLE beta
+#define BLENDER_VERSION_CYCLE alpha
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 14
+#define BLENDER_FILE_SUBVERSION 7
/* 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
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index 84a17136361..78908908343 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -38,6 +38,7 @@ struct BMEditMesh;
struct MFace;
struct MVert;
struct Mesh;
+struct PointCloud;
struct BVHCache;
@@ -249,6 +250,20 @@ float bvhtree_sphereray_tri_intersection(const BVHTreeRay *ray,
const float v1[3],
const float v2[3]);
+typedef struct BVHTreeFromPointCloud {
+ struct BVHTree *tree;
+
+ BVHTree_NearestPointCallback nearest_callback;
+
+ const float (*coords)[3];
+} BVHTreeFromPointCloud;
+
+BVHTree *BKE_bvhtree_from_pointcloud_get(struct BVHTreeFromPointCloud *data,
+ const struct PointCloud *pointcloud,
+ const int tree_type);
+
+void free_bvhtree_from_pointcloud(struct BVHTreeFromPointCloud *data);
+
/**
* BVHCache
*/
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 3cba47afc46..231a4563630 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -121,7 +121,8 @@ void BKE_effector_relations_free(struct ListBase *lb);
struct ListBase *BKE_effectors_create(struct Depsgraph *depsgraph,
struct Object *ob_src,
struct ParticleSystem *psys_src,
- struct EffectorWeights *weights);
+ struct EffectorWeights *weights,
+ bool use_rotation);
void BKE_effectors_apply(struct ListBase *effectors,
struct ListBase *colliders,
struct EffectorWeights *weights,
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 31739465afd..5f1ddea0f13 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -37,6 +37,7 @@ struct Collection;
struct Mesh;
struct Object;
struct PointCloud;
+struct Volume;
/* Each geometry component has a specific type. The type determines what kind of data the component
* stores. Functions modifying a geometry will usually just modify a subset of the component types.
@@ -45,6 +46,7 @@ enum class GeometryComponentType {
Mesh = 0,
PointCloud = 1,
Instances = 2,
+ Volume = 3,
};
enum class GeometryOwnershipType {
@@ -66,6 +68,10 @@ template<> struct DefaultHash<GeometryComponentType> {
};
} // namespace blender
+namespace blender::bke {
+class ComponentAttributeProviders;
+}
+
class GeometryComponent;
/**
@@ -150,40 +156,35 @@ class GeometryComponent {
bool attribute_exists(const blender::StringRef attribute_name) const;
/* Returns true when the geometry component supports this attribute domain. */
- virtual bool attribute_domain_supported(const AttributeDomain domain) const;
- /* Returns true when the given data type is supported in the given domain. */
- virtual bool attribute_domain_with_type_supported(const AttributeDomain domain,
- const CustomDataType data_type) const;
+ bool attribute_domain_supported(const AttributeDomain domain) const;
/* Can only be used with supported domain types. */
virtual int attribute_domain_size(const AttributeDomain domain) const;
- /* Attributes with these names cannot be created or removed via this api. */
- virtual bool attribute_is_builtin(const blender::StringRef attribute_name) const;
/* Get read-only access to the highest priority attribute with the given name.
* Returns null if the attribute does not exist. */
- virtual blender::bke::ReadAttributePtr attribute_try_get_for_read(
+ blender::bke::ReadAttributePtr attribute_try_get_for_read(
const blender::StringRef attribute_name) const;
/* Get read and write access to the highest priority attribute with the given name.
* Returns null if the attribute does not exist. */
- virtual blender::bke::WriteAttributePtr attribute_try_get_for_write(
+ blender::bke::WriteAttributePtr attribute_try_get_for_write(
const blender::StringRef attribute_name);
/* Get a read-only attribute for the domain based on the given attribute. This can be used to
* interpolate from one domain to another.
* Returns null if the interpolation is not implemented. */
virtual blender::bke::ReadAttributePtr attribute_try_adapt_domain(
- blender::bke::ReadAttributePtr attribute, const AttributeDomain domain) const;
+ blender::bke::ReadAttributePtr attribute, const AttributeDomain new_domain) const;
/* Returns true when the attribute has been deleted. */
- virtual bool attribute_try_delete(const blender::StringRef attribute_name);
+ bool attribute_try_delete(const blender::StringRef attribute_name);
/* Returns true when the attribute has been created. */
- virtual bool attribute_try_create(const blender::StringRef attribute_name,
- const AttributeDomain domain,
- const CustomDataType data_type);
+ bool attribute_try_create(const blender::StringRef attribute_name,
+ const AttributeDomain domain,
+ const CustomDataType data_type);
- virtual blender::Set<std::string> attribute_names() const;
+ blender::Set<std::string> attribute_names() const;
virtual bool is_empty() const;
/* Get a read-only attribute for the given domain and data type.
@@ -255,6 +256,9 @@ class GeometryComponent {
const AttributeDomain domain,
const CustomDataType data_type,
const void *default_value = nullptr);
+
+ private:
+ virtual const blender::bke::ComponentAttributeProviders *get_attribute_providers() const;
};
template<typename T>
@@ -320,10 +324,13 @@ struct GeometrySet {
bool has_mesh() const;
bool has_pointcloud() const;
bool has_instances() const;
+ bool has_volume() const;
const Mesh *get_mesh_for_read() const;
const PointCloud *get_pointcloud_for_read() const;
+ const Volume *get_volume_for_read() const;
Mesh *get_mesh_for_write();
PointCloud *get_pointcloud_for_write();
+ Volume *get_volume_for_write();
/* Utility methods for replacement. */
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
@@ -354,30 +361,22 @@ class MeshComponent : public GeometryComponent {
Mesh *release();
void copy_vertex_group_names_from_object(const struct Object &object);
+ const blender::Map<std::string, int> &vertex_group_names() const;
+ blender::Map<std::string, int> &vertex_group_names();
const Mesh *get_for_read() const;
Mesh *get_for_write();
- bool attribute_domain_supported(const AttributeDomain domain) const final;
- bool attribute_domain_with_type_supported(const AttributeDomain domain,
- const CustomDataType data_type) const final;
int attribute_domain_size(const AttributeDomain domain) const final;
- bool attribute_is_builtin(const blender::StringRef attribute_name) const final;
+ blender::bke::ReadAttributePtr attribute_try_adapt_domain(
+ blender::bke::ReadAttributePtr attribute, const AttributeDomain new_domain) const final;
- blender::bke::ReadAttributePtr attribute_try_get_for_read(
- const blender::StringRef attribute_name) const final;
- blender::bke::WriteAttributePtr attribute_try_get_for_write(
- const blender::StringRef attribute_name) final;
-
- bool attribute_try_delete(const blender::StringRef attribute_name) final;
- bool attribute_try_create(const blender::StringRef attribute_name,
- const AttributeDomain domain,
- const CustomDataType data_type) final;
-
- blender::Set<std::string> attribute_names() const final;
bool is_empty() const final;
static constexpr inline GeometryComponentType static_type = GeometryComponentType::Mesh;
+
+ private:
+ const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
};
/** A geometry component that stores a point cloud. */
@@ -400,26 +399,14 @@ class PointCloudComponent : public GeometryComponent {
const PointCloud *get_for_read() const;
PointCloud *get_for_write();
- bool attribute_domain_supported(const AttributeDomain domain) const final;
- bool attribute_domain_with_type_supported(const AttributeDomain domain,
- const CustomDataType data_type) const final;
int attribute_domain_size(const AttributeDomain domain) const final;
- bool attribute_is_builtin(const blender::StringRef attribute_name) const final;
-
- blender::bke::ReadAttributePtr attribute_try_get_for_read(
- const blender::StringRef attribute_name) const final;
- blender::bke::WriteAttributePtr attribute_try_get_for_write(
- const blender::StringRef attribute_name) final;
- bool attribute_try_delete(const blender::StringRef attribute_name) final;
- bool attribute_try_create(const blender::StringRef attribute_name,
- const AttributeDomain domain,
- const CustomDataType data_type) final;
-
- blender::Set<std::string> attribute_names() const final;
bool is_empty() const final;
static constexpr inline GeometryComponentType static_type = GeometryComponentType::PointCloud;
+
+ private:
+ const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
};
/** A geometry component that stores instances. */
@@ -449,3 +436,25 @@ class InstancesComponent : public GeometryComponent {
static constexpr inline GeometryComponentType static_type = GeometryComponentType::Instances;
};
+
+/** A geometry component that stores volume grids. */
+class VolumeComponent : public GeometryComponent {
+ private:
+ Volume *volume_ = nullptr;
+ GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
+
+ public:
+ VolumeComponent();
+ ~VolumeComponent();
+ GeometryComponent *copy() const override;
+
+ void clear();
+ bool has_volume() const;
+ void replace(Volume *volume, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+ Volume *release();
+
+ const Volume *get_for_read() const;
+ Volume *get_for_write();
+
+ static constexpr inline GeometryComponentType static_type = GeometryComponentType::Volume;
+};
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 5e16c9c979c..d6b6ffd425e 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -59,7 +59,7 @@ typedef struct Global {
short moving;
- /** To indicate render is busy, prevent renderwindow events etc. */
+ /** To indicate render is busy, prevent render-window events etc. */
bool is_rendering;
/**
@@ -147,21 +147,18 @@ enum {
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_MEM = (1 << 16), /* gpu memory in status bar */
- G_DEBUG_GPU = (1 << 17), /* gpu debug */
- G_DEBUG_IO = (1 << 18), /* IO Debugging (for Collada, ...)*/
- G_DEBUG_GPU_SHADERS = (1 << 19), /* GLSL shaders */
- G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 20), /* force gpu workarounds bypassing detections. */
- G_DEBUG_XR = (1 << 21), /* XR/OpenXR messages */
- G_DEBUG_XR_TIME = (1 << 22), /* XR/OpenXR timing messages */
-
- G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */
+ 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. */
};
#define G_DEBUG_ALL \
(G_DEBUG | G_DEBUG_FFMPEG | G_DEBUG_PYTHON | G_DEBUG_EVENTS | G_DEBUG_WM | G_DEBUG_JOBS | \
- G_DEBUG_FREESTYLE | G_DEBUG_DEPSGRAPH | G_DEBUG_GPU_MEM | G_DEBUG_IO | G_DEBUG_GPU_SHADERS | \
- G_DEBUG_GHOST)
+ G_DEBUG_FREESTYLE | G_DEBUG_DEPSGRAPH | G_DEBUG_IO | G_DEBUG_GHOST)
/** #Global.fileflags */
enum {
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index df5711f5120..a8caf317467 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -109,9 +109,14 @@ struct bGPDframe *BKE_gpencil_frame_addcopy(struct bGPDlayer *gpl, int cframe);
struct bGPDlayer *BKE_gpencil_layer_addnew(struct bGPdata *gpd, const char *name, bool setactive);
struct bGPdata *BKE_gpencil_data_addnew(struct Main *bmain, const char name[]);
-struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src);
-struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src);
+struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src,
+ const bool dup_strokes);
+struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src,
+ const bool dup_frames,
+ const bool dup_strokes);
void BKE_gpencil_frame_copy_strokes(struct bGPDframe *gpf_src, struct bGPDframe *gpf_dst);
+void BKE_gpencil_frame_selected_hash(struct bGPdata *gpd, struct GHash *r_list);
+
struct bGPDcurve *BKE_gpencil_stroke_curve_duplicate(struct bGPDcurve *gpc_src);
struct bGPDstroke *BKE_gpencil_stroke_duplicate(struct bGPDstroke *gps_src,
const bool dup_points,
@@ -280,12 +285,12 @@ void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig
const struct bGPDframe *gpf_eval);
void BKE_gpencil_update_orig_pointers(const struct Object *ob_orig, const struct Object *ob_eval);
-void BKE_gpencil_parent_matrix_get(const struct Depsgraph *depsgraph,
- struct Object *obact,
- struct bGPDlayer *gpl,
- float diff_mat[4][4]);
+void BKE_gpencil_layer_transform_matrix_get(const struct Depsgraph *depsgraph,
+ struct Object *obact,
+ struct bGPDlayer *gpl,
+ float diff_mat[4][4]);
-void BKE_gpencil_update_layer_parent(const struct Depsgraph *depsgraph, struct Object *ob);
+void BKE_gpencil_update_layer_transforms(const struct Depsgraph *depsgraph, struct Object *ob);
int BKE_gpencil_material_find_index_by_name_prefix(struct Object *ob, const char *name_prefix);
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index 1c86df73d3c..89a794f2df3 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -149,6 +149,11 @@ void BKE_gpencil_stroke_join(struct bGPDstroke *gps_a,
struct bGPDstroke *gps_b,
const bool leave_gaps,
const bool fit_thickness);
+void BKE_gpencil_stroke_copy_to_keyframes(struct bGPdata *gpd,
+ struct bGPDlayer *gpl,
+ struct bGPDframe *gpf,
+ struct bGPDstroke *gps,
+ const bool tail);
bool BKE_gpencil_convert_mesh(struct Main *bmain,
struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index 61ccf3d60f6..c066c161f46 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -248,7 +248,7 @@ typedef struct GpencilModifierTypeInfo {
#define GPENCIL_MODIFIER_TYPE_PANEL_PREFIX "MOD_PT_gpencil_"
-/* Initialize modifier's global data (type info and some common global storages). */
+/* Initialize modifier's global data (type info and some common global storage). */
void BKE_gpencil_modifier_init(void);
void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname);
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index 1298e3c2bbf..edfc96f3059 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -106,6 +106,8 @@ typedef void (*IDTypeBlendReadUndoPreserve)(struct BlendLibReader *reader,
struct ID *id_new,
struct ID *id_old);
+typedef void (*IDTypeLibOverrideApplyPost)(struct ID *id_dst, struct ID *id_src);
+
typedef struct IDTypeInfo {
/* ********** General IDType data. ********** */
@@ -207,6 +209,13 @@ typedef struct IDTypeInfo {
* \note Called from #setup_app_data when undoing or redoing a memfile step.
*/
IDTypeBlendReadUndoPreserve blend_read_undo_preserve;
+
+ /**
+ * Called after library override operations have been applied.
+ *
+ * \note Currently needed for some update operation on point caches.
+ */
+ IDTypeLibOverrideApplyPost lib_override_apply_post;
} IDTypeInfo;
/* ********** Declaration of each IDTypeInfo. ********** */
diff --git a/source/blender/blenkernel/BKE_keyconfig.h b/source/blender/blenkernel/BKE_keyconfig.h
index ab42d5742ea..1cacbf61976 100644
--- a/source/blender/blenkernel/BKE_keyconfig.h
+++ b/source/blender/blenkernel/BKE_keyconfig.h
@@ -43,10 +43,10 @@ typedef struct wmKeyConfigPrefType_Runtime {
typedef struct wmKeyConfigPrefType_Runtime wmKeyConfigPrefType_Runtime;
#endif
-/* KeyConfig preferenes (UserDef). */
+/* KeyConfig preferences (UserDef). */
struct wmKeyConfigPref *BKE_keyconfig_pref_ensure(struct UserDef *userdef, const char *kc_idname);
-/* KeyConfig preferenes (RNA). */
+/* KeyConfig preferences (RNA). */
struct wmKeyConfigPrefType_Runtime *BKE_keyconfig_pref_type_find(const char *idname, bool quiet);
void BKE_keyconfig_pref_type_add(struct wmKeyConfigPrefType_Runtime *kpt_rt);
void BKE_keyconfig_pref_type_remove(const struct wmKeyConfigPrefType_Runtime *kpt_rt);
diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index cfd1db1317c..5a8d36b94ec 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -219,7 +219,7 @@ void id_fake_user_set(struct ID *id);
void id_fake_user_clear(struct ID *id);
void BKE_id_clear_newpoin(struct ID *id);
-/** Flags to control make local code behaviour. */
+/** Flags to control make local code behavior. */
enum {
/** Making that ID local is part of making local a whole library. */
LIB_ID_MAKELOCAL_FULL_LIBRARY = 1 << 0,
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index c9a9c26e222..5fd451dc986 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -65,15 +65,6 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
struct ID *reference_id,
const bool do_tagged_remap);
bool BKE_lib_override_library_create_from_tag(struct Main *bmain);
-void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
- struct ID *id_root,
- const uint tag,
- const bool do_create_main_relashionships);
-void BKE_lib_override_library_override_group_tag(struct Main *bmain,
- struct ID *id_root,
- const uint tag,
- const uint missing_tag,
- const bool do_create_main_relashionships);
bool BKE_lib_override_library_create(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h
index b6abe0bf18c..bdda5bb0372 100644
--- a/source/blender/blenkernel/BKE_lib_query.h
+++ b/source/blender/blenkernel/BKE_lib_query.h
@@ -77,7 +77,7 @@ enum {
IDWALK_CB_USER = (1 << 8),
/**
* This ID usage is not refcounted, but at least one user should be generated by it (to avoid
- * e.g. loosing the used ID on save/reload).
+ * e.g. losing the used ID on save/reload).
* Callback is responsible to deal accordingly with #ID.us if needed.
*/
IDWALK_CB_USER_ONE = (1 << 9),
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 8106607572b..b6116b32ca5 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -60,22 +60,52 @@ typedef struct BlendThumbnail {
} BlendThumbnail;
/* Structs caching relations between data-blocks in a given Main. */
+typedef struct MainIDRelationsEntryItem {
+ struct MainIDRelationsEntryItem *next;
+
+ union {
+ /* For `from_ids` list, a user of the hashed ID. */
+ struct ID *from;
+ /* For `to_ids` list, an ID used by the hashed ID. */
+ struct ID **to;
+ } id_pointer;
+ /* Session uuid of the `id_pointer`. */
+ uint session_uuid;
+
+ int usage_flag; /* Using IDWALK_ enums, defined in BKE_lib_query.h */
+} MainIDRelationsEntryItem;
+
typedef struct MainIDRelationsEntry {
- struct MainIDRelationsEntry *next;
- /* WARNING! for user_to_used,
- * that pointer is really an ID** one, but for used_to_user, it’s only an ID* one! */
- struct ID **id_pointer;
- int usage_flag; /* Using IDWALK_ enums, in BKE_lib_query.h */
+ /* Linked list of IDs using that ID. */
+ struct MainIDRelationsEntryItem *from_ids;
+ /* Linked list of IDs used by that ID. */
+ struct MainIDRelationsEntryItem *to_ids;
+
+ /* Session uuid of the ID matching that entry. */
+ uint session_uuid;
+
+ /* Runtime tags, users should ensure those are reset after usage. */
+ uint tags;
} MainIDRelationsEntry;
+/* MainIDRelationsEntry.tags */
+typedef enum MainIDRelationsEntryTags {
+ /* Generic tag marking the entry as to be processed. */
+ MAINIDRELATIONS_ENTRY_TAGS_DOIT = 1 << 0,
+ /* Generic tag marking the entry as processed. */
+ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED = 1 << 1,
+} MainIDRelationsEntryTags;
+
typedef struct MainIDRelations {
- struct GHash *id_user_to_used;
- struct GHash *id_used_to_user;
+ /* Mapping from an ID pointer to all of its parents (IDs using it) and children (IDs it uses).
+ * Values are `MainIDRelationsEntry` pointers. */
+ struct GHash *relations_from_pointers;
+ /* Note: we could add more mappings when needed (e.g. from session uuid?). */
short flag;
/* Private... */
- struct BLI_mempool *entry_pool;
+ struct BLI_mempool *entry_items_pool;
} MainIDRelations;
enum {
@@ -172,7 +202,9 @@ void BKE_main_unlock(struct Main *bmain);
void BKE_main_relations_create(struct Main *bmain, const short flag);
void BKE_main_relations_free(struct Main *bmain);
-void BKE_main_relations_ID_remove(struct Main *bmain, struct ID *id);
+void BKE_main_relations_tag_set(struct Main *bmain,
+ const MainIDRelationsEntryTags tag,
+ const bool value);
struct GSet *BKE_main_gset_create(struct Main *bmain, struct GSet *gset);
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index 29072742f81..8e2f6e6f10c 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -269,18 +269,18 @@ int BKE_mask_spline_differentiate_calc_total(const struct MaskSpline *spline,
const unsigned int resol);
float (*BKE_mask_spline_differentiate_with_resolution(struct MaskSpline *spline,
- unsigned int *tot_diff_point,
- const unsigned int resol))[2];
+ const unsigned int resol,
+ unsigned int *r_tot_diff_point))[2];
void BKE_mask_spline_feather_collapse_inner_loops(struct MaskSpline *spline,
float (*feather_points)[2],
const unsigned int tot_feather_point);
float (*BKE_mask_spline_differentiate(
- struct MaskSpline *spline, int width, int height, unsigned int *tot_diff_point))[2];
+ struct MaskSpline *spline, int width, int height, unsigned int *r_tot_diff_point))[2];
float (*BKE_mask_spline_feather_differentiated_points_with_resolution(
struct MaskSpline *spline,
- unsigned int *tot_feather_point,
const unsigned int resol,
- const bool do_feather_isect))[2];
+ const bool do_feather_isect,
+ unsigned int *r_tot_feather_point))[2];
/* *** mask point functions which involve evaluation *** */
float (*BKE_mask_spline_feather_points(struct MaskSpline *spline, int *tot_feather_point))[2];
@@ -289,7 +289,7 @@ float *BKE_mask_point_segment_diff(struct MaskSpline *spline,
struct MaskSplinePoint *point,
int width,
int height,
- unsigned int *tot_diff_point);
+ unsigned int *r_tot_diff_point);
float *BKE_mask_point_segment_feather_diff(struct MaskSpline *spline,
struct MaskSplinePoint *point,
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 685a8ed98e2..32b74d161b2 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -399,7 +399,7 @@ typedef struct ModifierTypeInfo {
/* Used to find a modifier's panel type. */
#define MODIFIER_TYPE_PANEL_PREFIX "MOD_PT_"
-/* Initialize modifier's global data (type info and some common global storages). */
+/* Initialize modifier's global data (type info and some common global storage). */
void BKE_modifier_init(void);
const ModifierTypeInfo *BKE_modifier_get_info(ModifierType type);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 79bc00766fd..7984bbc980a 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -419,7 +419,7 @@ struct GHashIterator *ntreeTypeGetIterator(void);
GHashIterator *__node_tree_type_iter__ = ntreeTypeGetIterator(); \
for (; !BLI_ghashIterator_done(__node_tree_type_iter__); \
BLI_ghashIterator_step(__node_tree_type_iter__)) { \
- bNodeTreeType *ntype = BLI_ghashIterator_getValue(__node_tree_type_iter__);
+ bNodeTreeType *ntype = (bNodeTreeType *)BLI_ghashIterator_getValue(__node_tree_type_iter__);
#define NODE_TREE_TYPES_END \
} \
@@ -453,7 +453,9 @@ void ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree);
void ntreeUpdateAllNew(struct Main *main);
void ntreeUpdateAllUsers(struct Main *main, struct ID *id);
-void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes);
+void ntreeGetDependencyList(struct bNodeTree *ntree,
+ struct bNode ***r_deplist,
+ int *r_deplist_len);
/* XXX old trees handle output flags automatically based on special output
* node types and last active selection.
@@ -463,8 +465,8 @@ void ntreeSetOutput(struct bNodeTree *ntree);
void ntreeFreeCache(struct bNodeTree *ntree);
-bool ntreeNodeExists(struct bNodeTree *ntree, struct bNode *testnode);
-bool ntreeOutputExists(struct bNode *node, struct bNodeSocket *testsock);
+bool ntreeNodeExists(const struct bNodeTree *ntree, const struct bNode *testnode);
+bool ntreeOutputExists(const struct bNode *node, const struct bNodeSocket *testsock);
void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable);
struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree);
void ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree);
@@ -501,7 +503,7 @@ struct bNodeSocket *ntreeInsertSocketInterfaceFromSocket(struct bNodeTree *ntree
struct bNodeSocket *from_sock);
void ntreeRemoveSocketInterface(struct bNodeTree *ntree, struct bNodeSocket *sock);
-struct StructRNA *ntreeInterfaceTypeGet(struct bNodeTree *ntree, int create);
+struct StructRNA *ntreeInterfaceTypeGet(struct bNodeTree *ntree, bool create);
void ntreeInterfaceTypeFree(struct bNodeTree *ntree);
void ntreeInterfaceTypeUpdate(struct bNodeTree *ntree);
@@ -523,7 +525,7 @@ struct GHashIterator *nodeTypeGetIterator(void);
GHashIterator *__node_type_iter__ = nodeTypeGetIterator(); \
for (; !BLI_ghashIterator_done(__node_type_iter__); \
BLI_ghashIterator_step(__node_type_iter__)) { \
- bNodeType *ntype = BLI_ghashIterator_getValue(__node_type_iter__);
+ bNodeType *ntype = (bNodeType *)BLI_ghashIterator_getValue(__node_type_iter__);
#define NODE_TYPES_END \
} \
@@ -545,7 +547,8 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype);
GHashIterator *__node_socket_type_iter__ = nodeSocketTypeGetIterator(); \
for (; !BLI_ghashIterator_done(__node_socket_type_iter__); \
BLI_ghashIterator_step(__node_socket_type_iter__)) { \
- bNodeSocketType *stype = BLI_ghashIterator_getValue(__node_socket_type_iter__);
+ bNodeSocketType *stype = (bNodeSocketType *)BLI_ghashIterator_getValue( \
+ __node_socket_type_iter__);
#define NODE_SOCKET_TYPES_END \
} \
@@ -624,12 +627,12 @@ struct bNodeLink *nodeAddLink(struct bNodeTree *ntree,
struct bNodeSocket *tosock);
void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link);
void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
-bool nodeLinkIsHidden(struct bNodeLink *link);
+bool nodeLinkIsHidden(const struct bNodeLink *link);
void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node);
-void nodeToView(struct bNode *node, float x, float y, float *rx, float *ry);
-void nodeFromView(struct bNode *node, float x, float y, float *rx, float *ry);
-bool nodeAttachNodeCheck(struct bNode *node, struct bNode *parent);
+void nodeToView(const struct bNode *node, float x, float y, float *rx, float *ry);
+void nodeFromView(const struct bNode *node, float x, float y, float *rx, float *ry);
+bool nodeAttachNodeCheck(const struct bNode *node, const struct bNode *parent);
void nodeAttachNode(struct bNode *node, struct bNode *parent);
void nodeDetachNode(struct bNode *node);
@@ -661,9 +664,9 @@ void nodeChainIterBackwards(const bNodeTree *ntree,
void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata);
struct bNodeLink *nodeFindLink(struct bNodeTree *ntree,
- struct bNodeSocket *from,
- struct bNodeSocket *to);
-int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
+ const struct bNodeSocket *from,
+ const struct bNodeSocket *to);
+int nodeCountSocketLinks(const struct bNodeTree *ntree, const struct bNodeSocket *sock);
void nodeSetSelected(struct bNode *node, bool select);
void nodeSetActive(struct bNodeTree *ntree, struct bNode *node);
@@ -678,14 +681,14 @@ void nodeUpdate(struct bNodeTree *ntree, struct bNode *node);
bool nodeUpdateID(struct bNodeTree *ntree, struct ID *id);
void nodeUpdateInternalLinks(struct bNodeTree *ntree, struct bNode *node);
-int nodeSocketIsHidden(struct bNodeSocket *sock);
+int nodeSocketIsHidden(const struct bNodeSocket *sock);
void ntreeTagUsedSockets(struct bNodeTree *ntree);
void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available);
-int nodeSocketLinkLimit(struct bNodeSocket *sock);
+int nodeSocketLinkLimit(const struct bNodeSocket *sock);
/* Node Clipboard */
-void BKE_node_clipboard_init(struct bNodeTree *ntree);
+void BKE_node_clipboard_init(const struct bNodeTree *ntree);
void BKE_node_clipboard_clear(void);
void BKE_node_clipboard_free(void);
bool BKE_node_clipboard_validate(void);
@@ -706,8 +709,8 @@ extern const bNodeInstanceKey NODE_INSTANCE_KEY_BASE;
extern const bNodeInstanceKey NODE_INSTANCE_KEY_NONE;
bNodeInstanceKey BKE_node_instance_key(bNodeInstanceKey parent_key,
- struct bNodeTree *ntree,
- struct bNode *node);
+ const struct bNodeTree *ntree,
+ const struct bNode *node);
bNodeInstanceHash *BKE_node_instance_hash_new(const char *info);
void BKE_node_instance_hash_free(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp);
@@ -767,7 +770,7 @@ BLI_INLINE bool BKE_node_instance_hash_iterator_done(bNodeInstanceHashIterator *
/* Node Previews */
-int BKE_node_preview_used(struct bNode *node);
+bool BKE_node_preview_used(const struct bNode *node);
bNodePreview *BKE_node_preview_verify(
struct bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, bool create);
bNodePreview *BKE_node_preview_copy(struct bNodePreview *preview);
@@ -1361,6 +1364,14 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define GEO_NODE_ALIGN_ROTATION_TO_VECTOR 1018
#define GEO_NODE_POINT_TRANSLATE 1019
#define GEO_NODE_POINT_SCALE 1020
+#define GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE 1021
+#define GEO_NODE_POINTS_TO_VOLUME 1022
+#define GEO_NODE_COLLECTION_INFO 1023
+#define GEO_NODE_IS_VIEWPORT 1024
+#define GEO_NODE_ATTRIBUTE_PROXIMITY 1025
+#define GEO_NODE_VOLUME_TO_MESH 1026
+#define GEO_NODE_ATTRIBUTE_COMBINE_XYZ 1027
+#define GEO_NODE_ATTRIBUTE_SEPARATE_XYZ 1028
/** \} */
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 0a35658464a..4369f332c35 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -365,7 +365,7 @@ typedef struct SculptBoundaryEditInfo {
/* How many steps were needed to reach this vertex from the boundary. */
int num_propagation_steps;
- /* Stregth that is used to deform this vertex. */
+ /* Strength that is used to deform this vertex. */
float strength_factor;
} SculptBoundaryEditInfo;
@@ -530,7 +530,7 @@ typedef struct SculptSession {
float gesture_initial_normal[3];
bool gesture_initial_hit;
- /* TODO(jbakker): Replace rv3d adn v3d with ViewContext */
+ /* TODO(jbakker): Replace rv3d and v3d with ViewContext */
struct RegionView3D *rv3d;
struct View3D *v3d;
struct Scene *scene;
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 7b5df98d148..2fc0caf1a2c 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -67,6 +67,13 @@ struct wmWindowManager;
#define BKE_ST_MAXNAME 64
+typedef struct wmSpaceTypeListenerParams {
+ struct wmWindow *window;
+ struct ScrArea *area;
+ struct wmNotifier *notifier;
+ const struct Scene *scene;
+} wmSpaceTypeListenerParams;
+
typedef struct SpaceType {
struct SpaceType *next, *prev;
@@ -85,10 +92,7 @@ typedef struct SpaceType {
/* exit is called when the area is hidden or removed */
void (*exit)(struct wmWindowManager *wm, struct ScrArea *area);
/* Listeners can react to bContext changes */
- void (*listener)(struct wmWindow *win,
- struct ScrArea *area,
- struct wmNotifier *wmn,
- struct Scene *scene);
+ void (*listener)(const wmSpaceTypeListenerParams *params);
/* called when the mouse moves out of the area */
void (*deactivate)(struct ScrArea *area);
@@ -134,6 +138,24 @@ typedef struct SpaceType {
/* region types are also defined using spacetypes_init, via a callback */
+typedef struct wmRegionListenerParams {
+ struct wmWindow *window;
+ struct ScrArea *area; /* Can be NULL when the region is not part of an area. */
+ struct ARegion *region;
+ struct wmNotifier *notifier;
+ const struct Scene *scene;
+} wmRegionListenerParams;
+
+typedef struct wmRegionMessageSubscribeParams {
+ const struct bContext *context;
+ struct wmMsgBus *message_bus;
+ struct WorkSpace *workspace;
+ struct Scene *scene;
+ struct bScreen *screen;
+ struct ScrArea *area;
+ struct ARegion *region;
+} wmRegionMessageSubscribeParams;
+
typedef struct ARegionType {
struct ARegionType *next, *prev;
@@ -158,19 +180,9 @@ typedef struct ARegionType {
/* snap the size of the region (can be NULL for no snapping). */
int (*snap_size)(const struct ARegion *region, int size, int axis);
/* contextual changes should be handled here */
- void (*listener)(struct wmWindow *win,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmNotifier *wmn,
- const struct Scene *scene);
+ void (*listener)(const wmRegionListenerParams *params);
/* Optional callback to generate subscriptions. */
- void (*message_subscribe)(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+ void (*message_subscribe)(const wmRegionMessageSubscribeParams *params);
void (*free)(struct ARegion *);
diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h
index 23bd62c70bc..e385f77565b 100644
--- a/source/blender/blenkernel/BKE_shader_fx.h
+++ b/source/blender/blenkernel/BKE_shader_fx.h
@@ -149,7 +149,7 @@ typedef struct ShaderFxTypeInfo {
#define SHADERFX_TYPE_PANEL_PREFIX "FX_PT_"
-/* Initialize global data (type info and some common global storages). */
+/* Initialize global data (type info and some common global storage). */
void BKE_shaderfx_init(void);
void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname);
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index d1cffd26432..4f8b21141b6 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -49,7 +49,7 @@ typedef struct BodyPoint {
/* allocates and initializes general main data */
extern struct SoftBody *sbNew(struct Scene *scene);
-/* frees internal data and softbody itself */
+/* frees internal data and soft-body itself */
extern void sbFree(struct Object *ob);
/* frees simulation data to reset simulation */
@@ -66,7 +66,7 @@ extern void sbObjectStep(struct Depsgraph *depsgraph,
/* makes totally fresh start situation, resets time */
extern void sbObjectToSoftbody(struct Object *ob);
-/* links the softbody module to a 'test for Interrupt' function */
+/* links the soft-body module to a 'test for Interrupt' function */
/* pass NULL to unlink again */
extern void sbSetInterruptCallBack(int (*f)(void));
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index f0ca154c4b9..b7d4ab8d8ed 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -293,7 +293,7 @@ bool BKE_subdiv_ccg_check_coord_valid(const SubdivCCG *subdiv_ccg, const SubdivC
* neighbor elements in total).
*
* - For the corner element a single neighboring element on every adjacent edge, single from
- * every gird.
+ * every grid.
*
* - For the boundary element two neighbor elements on the boundary (from same grid) and one
* element inside of every neighboring grid. */
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 4dbc22ae18f..c2544c06514 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -89,6 +89,23 @@ struct MovieTrackingTrack *BKE_tracking_track_duplicate(struct MovieTrackingTrac
void BKE_tracking_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
void BKE_tracking_track_free(struct MovieTrackingTrack *track);
+void BKE_tracking_track_first_last_frame_get(const struct MovieTrackingTrack *track,
+ int *r_first_frame,
+ int *r_last_frame);
+
+void BKE_tracking_tracks_first_last_frame_minmax(/*const*/ struct MovieTrackingTrack **tracks,
+ const int num_tracks,
+ int *r_first_frame,
+ int *r_last_frame);
+
+int BKE_tracking_count_selected_tracks_in_list(const struct ListBase *tracks_list);
+int BKE_tracking_count_selected_tracks_in_active_object(/*const*/ struct MovieTracking *tracking);
+
+/* Get array of selected tracks from the current active object in the tracking structure.
+ * If nothing is selected then the result is nullptr and `r_num_tracks` is set to 0. */
+struct MovieTrackingTrack **BKE_tracking_selected_tracks_in_active_object(
+ struct MovieTracking *tracking, int *r_num_tracks);
+
void BKE_tracking_track_flag_set(struct MovieTrackingTrack *track, int area, int flag);
void BKE_tracking_track_flag_clear(struct MovieTrackingTrack *track, int area, int flag);
@@ -96,10 +113,15 @@ bool BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, in
bool BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr);
void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action);
+
void BKE_tracking_tracks_join(struct MovieTracking *tracking,
struct MovieTrackingTrack *dst_track,
struct MovieTrackingTrack *src_track);
+void BKE_tracking_tracks_average(struct MovieTrackingTrack *dst_track,
+ /*const*/ struct MovieTrackingTrack **src_tracks,
+ const int num_src_tracks);
+
struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking,
struct MovieTrackingObject *object,
const char *name);
@@ -139,6 +161,17 @@ struct MovieTrackingMarker *BKE_tracking_marker_get_exact(struct MovieTrackingTr
struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct MovieTrackingTrack *track,
int framenr);
+/* Get marker position, possibly interpolating interpolating gap between keyframed/tracked markers.
+ *
+ * The result marker frame number is set to the requested frame number. Its flags are 0 if the
+ * marker is interpolated, and is set to original marker flag if there were no interpolation
+ * involved.
+ *
+ * Returns truth if the result is usable. */
+bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track,
+ const int framenr,
+ struct MovieTrackingMarker *r_marker);
+
void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker *marker,
float min[2],
float max[2]);
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index 0603ef85cc1..620496864f5 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -96,6 +96,12 @@ typedef struct UndoStep {
/* Over alloc 'type->struct_size'. */
} UndoStep;
+typedef enum eUndoStepDir {
+ STEP_REDO = 1,
+ STEP_UNDO = -1,
+ STEP_INVALID = 0,
+} eUndoStepDir;
+
typedef enum UndoPushReturn {
UNDO_PUSH_RET_FAILURE = 0,
UNDO_PUSH_RET_SUCCESS = (1 << 0),
@@ -127,7 +133,7 @@ typedef struct UndoType {
bool (*step_encode)(struct bContext *C, struct Main *bmain, UndoStep *us);
void (*step_decode)(
- struct bContext *C, struct Main *bmain, UndoStep *us, int dir, bool is_final);
+ struct bContext *C, struct Main *bmain, UndoStep *us, const eUndoStepDir dir, bool is_final);
/**
* \note When freeing all steps,
@@ -203,23 +209,32 @@ UndoStep *BKE_undosys_step_find_by_name_with_type(UndoStack *ustack,
UndoStep *BKE_undosys_step_find_by_type(UndoStack *ustack, const UndoType *ut);
UndoStep *BKE_undosys_step_find_by_name(UndoStack *ustack, const char *name);
+eUndoStepDir BKE_undosys_step_calc_direction(const UndoStack *ustack,
+ const UndoStep *us_target,
+ const UndoStep *us_reference);
+
+bool BKE_undosys_step_load_data_ex(UndoStack *ustack,
+ struct bContext *C,
+ UndoStep *us_target,
+ UndoStep *us_reference,
+ const bool use_skip);
+bool BKE_undosys_step_load_data(UndoStack *ustack, struct bContext *C, UndoStep *us_target);
+void BKE_undosys_step_load_from_index(UndoStack *ustack, struct bContext *C, const int index);
+
bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
struct bContext *C,
UndoStep *us,
bool use_skip);
-bool BKE_undosys_step_undo_with_data(UndoStack *ustack, struct bContext *C, UndoStep *us);
+bool BKE_undosys_step_undo_with_data(UndoStack *ustack, struct bContext *C, UndoStep *us_target);
bool BKE_undosys_step_undo(UndoStack *ustack, struct bContext *C);
bool BKE_undosys_step_redo_with_data_ex(UndoStack *ustack,
struct bContext *C,
UndoStep *us,
bool use_skip);
-bool BKE_undosys_step_redo_with_data(UndoStack *ustack, struct bContext *C, UndoStep *us);
+bool BKE_undosys_step_redo_with_data(UndoStack *ustack, struct bContext *C, UndoStep *us_target);
bool BKE_undosys_step_redo(UndoStack *ustack, struct bContext *C);
-bool BKE_undosys_step_load_data(UndoStack *ustack, struct bContext *C, UndoStep *us);
-
-void BKE_undosys_step_undo_from_index(UndoStack *ustack, struct bContext *C, int index);
UndoStep *BKE_undosys_step_same_type_next(UndoStep *us);
UndoStep *BKE_undosys_step_same_type_prev(UndoStep *us);
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 12c37ec56e0..53626dbeb1b 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -170,7 +170,7 @@ openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *vo
struct VolumeGrid *grid,
const bool clear);
-VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase::Ptr &grid);
+VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase &grid);
template<typename OpType>
auto BKE_volume_grid_type_operation(const VolumeGridType grid_type, OpType &&op)
diff --git a/intern/guardedalloc/mmap_win.h b/source/blender/blenkernel/BKE_volume_to_mesh.hh
index c0cbaa0e512..1ec8a8e84cd 100644
--- a/intern/guardedalloc/mmap_win.h
+++ b/source/blender/blenkernel/BKE_volume_to_mesh.hh
@@ -12,39 +12,32 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2008 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup MEM
*/
-#ifndef __MMAP_WIN_H__
-#define __MMAP_WIN_H__
-
-#define PROT_NONE 0
-#define PROT_READ 1
-#define PROT_WRITE 2
-#define PROT_EXEC 4
+#include "DNA_modifier_types.h"
-#define MAP_FILE 0
-#define MAP_SHARED 1
-#define MAP_PRIVATE 2
-#define MAP_TYPE 0xF
-#define MAP_FIXED 0x10
-#define MAP_ANONYMOUS 0x20
-#define MAP_ANON MAP_ANONYMOUS
-
-#define MAP_FAILED ((void *)-1)
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+#endif
-/* needed for uintptr_t, exception, dont use BLI anywhere else in MEM_* */
-#include "../../source/blender/blenlib/BLI_sys_types.h"
+struct Mesh;
+struct VolumeGrid;
-#include <sys/types.h>
+namespace blender::bke {
-void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset);
-intptr_t munmap(void *ptr, size_t size);
+struct VolumeToMeshResolution {
+ VolumeToMeshResolutionMode mode;
+ union {
+ float voxel_size;
+ float voxel_amount;
+ } settings;
+};
+#ifdef WITH_OPENVDB
+struct Mesh *volume_to_mesh(const openvdb::GridBase &grid,
+ const VolumeToMeshResolution &resolution,
+ const float threshold,
+ const float adaptivity);
#endif
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 9aa2baef53c..6b6d2b45d02 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -78,9 +78,10 @@ set(SRC
intern/armature.c
intern/armature_deform.c
intern/armature_update.c
- intern/asset.c
+ intern/asset.cc
intern/attribute.c
intern/attribute_access.cc
+ intern/attribute_math.cc
intern/autoexec.c
intern/blender.c
intern/blender_copybuffer.c
@@ -197,7 +198,7 @@ set(SRC
intern/multires_unsubdivide.c
intern/multires_versioning.c
intern/nla.c
- intern/node.c
+ intern/node.cc
intern/object.c
intern/object_deform.c
intern/object_dupli.c
@@ -259,6 +260,7 @@ set(SRC
intern/unit.c
intern/volume.cc
intern/volume_render.cc
+ intern/volume_to_mesh.cc
intern/workspace.c
intern/world.c
intern/writeavi.c
@@ -275,6 +277,7 @@ set(SRC
BKE_asset.h
BKE_attribute.h
BKE_attribute_access.hh
+ BKE_attribute_math.hh
BKE_autoexec.h
BKE_blender.h
BKE_blender_copybuffer.h
@@ -412,6 +415,7 @@ set(SRC
BKE_unit.h
BKE_volume.h
BKE_volume_render.h
+ BKE_volume_to_mesh.hh
BKE_workspace.h
BKE_world.h
BKE_writeavi.h
@@ -682,7 +686,7 @@ endif()
if(WITH_OPENVDB)
list(APPEND INC
- ../../../intern/openvdb
+ ../../../intern/openvdb
)
list(APPEND INC_SYS
${OPENVDB_INCLUDE_DIRS}
@@ -696,10 +700,10 @@ endif()
if(WITH_QUADRIFLOW)
list(APPEND INC
- ../../../intern/quadriflow
+ ../../../intern/quadriflow
)
list(APPEND LIB
- bf_intern_quadriflow
+ bf_intern_quadriflow
)
add_definitions(-DWITH_QUADRIFLOW)
endif()
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index ccb077d6b82..94680dc5c0c 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -54,6 +54,7 @@
#include "BKE_constraint.h"
#include "BKE_deform.h"
#include "BKE_fcurve.h"
+#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
@@ -101,10 +102,7 @@ static CLG_LogRef LOG = {"bke.action"};
*
* \param flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more).
*/
-static void action_copy_data(Main *UNUSED(bmain),
- ID *id_dst,
- const ID *id_src,
- const int UNUSED(flag))
+static void action_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
bAction *action_dst = (bAction *)id_dst;
const bAction *action_src = (const bAction *)id_src;
@@ -145,6 +143,13 @@ static void action_copy_data(Main *UNUSED(bmain),
}
}
}
+
+ if (flag & LIB_ID_COPY_NO_PREVIEW) {
+ action_dst->preview = NULL;
+ }
+ else {
+ BKE_previewimg_id_copy(&action_dst->id, &action_src->id);
+ }
}
/** Free (or release) any data used by this action (does not free the action itself). */
@@ -161,6 +166,8 @@ static void action_free_data(struct ID *id)
/* Free pose-references (aka local markers). */
BLI_freelistN(&action->markers);
+
+ BKE_previewimg_free(&action->preview);
}
static void action_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -192,6 +199,8 @@ static void action_blend_write(BlendWriter *writer, ID *id, const void *id_addre
LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
BLO_write_struct(writer, TimeMarker, marker);
}
+
+ BKE_previewimg_blend_write(writer, act->preview);
}
}
@@ -218,6 +227,9 @@ static void action_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &agrp->channels.first);
BLO_read_data_address(reader, &agrp->channels.last);
}
+
+ BLO_read_data_address(reader, &act->preview);
+ BKE_previewimg_blend_read(reader, act->preview);
}
static void blend_read_lib_constraint_channels(BlendLibReader *reader, ID *id, ListBase *chanbase)
@@ -298,6 +310,8 @@ IDTypeInfo IDType_ID_AC = {
.blend_read_expand = action_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* ***************** Library data level operations on action ************** */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 20956d6eb18..965dc4e0bec 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -362,6 +362,20 @@ void BKE_keyingsets_blend_read_expand(BlendExpander *expander, ListBase *list)
/* ***************************************** */
/* Evaluation Data-Setting Backend */
+static bool is_fcurve_evaluatable(FCurve *fcu)
+{
+ if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
+ return false;
+ }
+ if (fcu->grp != NULL && (fcu->grp->flag & AGRP_MUTED)) {
+ return false;
+ }
+ if (BKE_fcurve_is_empty(fcu)) {
+ return false;
+ }
+ return true;
+}
+
bool BKE_animsys_store_rna_setting(PointerRNA *ptr,
/* typically 'fcu->rna_path', 'fcu->array_index' */
const char *rna_path,
@@ -594,18 +608,11 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
{
/* Calculate then execute each curve. */
LISTBASE_FOREACH (FCurve *, fcu, list) {
- /* Check if this F-Curve doesn't belong to a muted group. */
- if ((fcu->grp != NULL) && (fcu->grp->flag & AGRP_MUTED)) {
- continue;
- }
- /* Check if this curve should be skipped. */
- if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))) {
- continue;
- }
- /* Skip empty curves, as if muted. */
- if (BKE_fcurve_is_empty(fcu)) {
+
+ if (!is_fcurve_evaluatable(fcu)) {
continue;
}
+
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
@@ -979,6 +986,19 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
return nes;
}
+static NlaEvalStrip *nlastrips_ctime_get_strip_single(
+ ListBase *dst_list,
+ NlaStrip *single_strip,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
+{
+ ListBase single_tracks_list;
+ single_tracks_list.first = single_tracks_list.last = single_strip;
+
+ return nlastrips_ctime_get_strip(
+ dst_list, &single_tracks_list, -1, anim_eval_context, flush_to_original);
+}
+
/* ---------------------- */
/* Initialize a valid mask, allocating memory if necessary. */
@@ -1152,11 +1172,7 @@ static void nlaeval_snapshot_free_data(NlaEvalSnapshot *snapshot)
/* Free memory owned by this evaluation channel. */
static void nlaevalchan_free_data(NlaEvalChannel *nec)
{
- nlavalidmask_free(&nec->valid);
-
- if (nec->blend_snapshot != NULL) {
- nlaevalchan_snapshot_free(nec->blend_snapshot);
- }
+ nlavalidmask_free(&nec->domain);
}
/* Initialize a full NLA evaluation state structure. */
@@ -1353,7 +1369,7 @@ static NlaEvalChannel *nlaevalchan_verify_key(NlaEvalData *nlaeval,
nec->mix_mode = nlaevalchan_detect_mix_mode(key, length);
- nlavalidmask_init(&nec->valid, length);
+ nlavalidmask_init(&nec->domain, length);
nec->base_snapshot.channel = nec;
nec->base_snapshot.length = length;
@@ -1578,7 +1594,7 @@ static bool nla_combine_get_inverted_strip_value(const int mix_mode,
if (IS_EQF(base_value, 0.0f)) {
base_value = 1.0f;
}
- /* Divison by zero. */
+ /* Division by zero. */
if (IS_EQF(lower_value, 0.0f)) {
/* Resolve 0/0 to 1. */
if (IS_EQF(blended_value, 0.0f)) {
@@ -1641,149 +1657,6 @@ static bool nla_combine_quaternion_get_inverted_strip_values(const float lower_v
return true;
}
-/* Data about the current blend mode. */
-typedef struct NlaBlendData {
- NlaEvalSnapshot *snapshot;
- int mode;
- float influence;
-
- NlaEvalChannel *blend_queue;
-} NlaBlendData;
-
-/* Queue the channel for deferred blending. */
-static NlaEvalChannelSnapshot *nlaevalchan_queue_blend(NlaBlendData *blend, NlaEvalChannel *nec)
-{
- if (!nec->in_blend) {
- if (nec->blend_snapshot == NULL) {
- nec->blend_snapshot = nlaevalchan_snapshot_new(nec);
- }
-
- nec->in_blend = true;
- nlaevalchan_snapshot_copy(nec->blend_snapshot, &nec->base_snapshot);
-
- nec->next_blend = blend->blend_queue;
- blend->blend_queue = nec;
- }
-
- return nec->blend_snapshot;
-}
-
-/* Accumulate (i.e. blend) the given value on to the channel it affects. */
-static bool nlaeval_blend_value(NlaBlendData *blend,
- NlaEvalChannel *nec,
- int array_index,
- float value)
-{
- if (nec == NULL) {
- return false;
- }
-
- if (!nlaevalchan_validate_index_ex(nec, array_index)) {
- return false;
- }
-
- if (nec->mix_mode == NEC_MIX_QUATERNION) {
- /* For quaternion properties, always output all sub-channels. */
- BLI_bitmap_set_all(nec->valid.ptr, true, 4);
- }
- else {
- BLI_BITMAP_ENABLE(nec->valid.ptr, array_index);
- }
-
- NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
- float *p_value = &nec_snapshot->values[array_index];
-
- if (blend->mode == NLASTRIP_MODE_COMBINE) {
- /* Quaternion blending is deferred until all sub-channel values are known. */
- if (nec->mix_mode == NEC_MIX_QUATERNION) {
- NlaEvalChannelSnapshot *blend_snapshot = nlaevalchan_queue_blend(blend, nec);
-
- blend_snapshot->values[array_index] = value;
- }
- else {
- float base_value = nec->base_snapshot.values[array_index];
-
- *p_value = nla_combine_value(nec->mix_mode, base_value, *p_value, value, blend->influence);
- }
- }
- else {
- *p_value = nla_blend_value(blend->mode, *p_value, value, blend->influence);
- }
-
- return true;
-}
-
-/* Finish deferred quaternion blending. */
-static void nlaeval_blend_flush(NlaBlendData *blend)
-{
- NlaEvalChannel *nec;
-
- while ((nec = blend->blend_queue)) {
- blend->blend_queue = nec->next_blend;
- nec->in_blend = false;
-
- NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
- NlaEvalChannelSnapshot *blend_snapshot = nec->blend_snapshot;
-
- if (nec->mix_mode == NEC_MIX_QUATERNION) {
- nla_combine_quaternion(
- nec_snapshot->values, blend_snapshot->values, blend->influence, nec_snapshot->values);
- }
- else {
- BLI_assert(!"mix quaternion");
- }
- }
-}
-
-/* Blend the specified snapshots into the target, and free the input snapshots. */
-static void nlaeval_snapshot_mix_and_free(NlaEvalData *nlaeval,
- NlaEvalSnapshot *out,
- NlaEvalSnapshot *in1,
- NlaEvalSnapshot *in2,
- float alpha)
-{
- BLI_assert(in1->base == out && in2->base == out);
-
- nlaeval_snapshot_ensure_size(out, nlaeval->num_channels);
-
- for (int i = 0; i < nlaeval->num_channels; i++) {
- NlaEvalChannelSnapshot *c_in1 = nlaeval_snapshot_get(in1, i);
- NlaEvalChannelSnapshot *c_in2 = nlaeval_snapshot_get(in2, i);
-
- if (c_in1 || c_in2) {
- NlaEvalChannelSnapshot *c_out = out->channels[i];
-
- /* Steal the entry from one of the input snapshots. */
- if (c_out == NULL) {
- if (c_in1 != NULL) {
- c_out = c_in1;
- in1->channels[i] = NULL;
- }
- else {
- c_out = c_in2;
- in2->channels[i] = NULL;
- }
- }
-
- if (c_in1 == NULL) {
- c_in1 = nlaeval_snapshot_find_channel(in1->base, c_out->channel);
- }
- if (c_in2 == NULL) {
- c_in2 = nlaeval_snapshot_find_channel(in2->base, c_out->channel);
- }
-
- out->channels[i] = c_out;
-
- for (int j = 0; j < c_out->length; j++) {
- c_out->values[j] = c_in1->values[j] * (1.0f - alpha) + c_in2->values[j] * alpha;
- }
- }
- }
-
- nlaeval_snapshot_free_data(in1);
- nlaeval_snapshot_free_data(in2);
-}
-
/* ---------------------- */
/* F-Modifier stack joining/separation utilities -
* should we generalize these for BLI_listbase.h interface? */
@@ -1845,6 +1718,50 @@ static void nlaeval_fmodifiers_split_stacks(ListBase *list1, ListBase *list2)
/* ---------------------- */
+/** Fills \a r_snapshot with the \a action's evaluated fcurve values with modifiers applied. */
+static void nlasnapshot_from_action(PointerRNA *ptr,
+ NlaEvalData *channels,
+ ListBase *modifiers,
+ bAction *action,
+ const float evaltime,
+ NlaEvalSnapshot *r_snapshot)
+{
+ FCurve *fcu;
+
+ action_idcode_patch_check(ptr->owner_id, action);
+
+ /* Evaluate modifiers which modify time to evaluate the base curves at. */
+ FModifiersStackStorage storage;
+ storage.modifier_count = BLI_listbase_count(modifiers);
+ storage.size_per_modifier = evaluate_fmodifiers_storage_size_per_modifier(modifiers);
+ storage.buffer = alloca(storage.modifier_count * storage.size_per_modifier);
+
+ const float modified_evaltime = evaluate_time_fmodifiers(
+ &storage, modifiers, NULL, 0.0f, evaltime);
+
+ for (fcu = action->curves.first; fcu; fcu = fcu->next) {
+ if (!is_fcurve_evaluatable(fcu)) {
+ continue;
+ }
+
+ NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
+
+ /* Invalid path or property cannot be animated. */
+ if (nec == NULL) {
+ continue;
+ }
+
+ NlaEvalChannelSnapshot *necs = nlaeval_snapshot_ensure_channel(r_snapshot, nec);
+ if (!nlaevalchan_validate_index_ex(nec, fcu->array_index)) {
+ continue;
+ }
+
+ float value = evaluate_fcurve(fcu, modified_evaltime);
+ evaluate_value_fmodifiers(&storage, modifiers, fcu, &value, evaltime);
+ necs->values[fcu->array_index] = value;
+ }
+}
+
/* evaluate action-clip strip */
static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
NlaEvalData *channels,
@@ -1852,10 +1769,8 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot)
{
- ListBase tmp_modifiers = {NULL, NULL};
+
NlaStrip *strip = nes->strip;
- FCurve *fcu;
- float evaltime;
/* sanity checks for action */
if (strip == NULL) {
@@ -1867,62 +1782,20 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
return;
}
- action_idcode_patch_check(ptr->owner_id, strip->act);
+ ListBase tmp_modifiers = {NULL, NULL};
/* join this strip's modifiers to the parent's modifiers (own modifiers first) */
nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
- /* evaluate strip's modifiers which modify time to evaluate the base curves at */
- FModifiersStackStorage storage;
- storage.modifier_count = BLI_listbase_count(&tmp_modifiers);
- storage.size_per_modifier = evaluate_fmodifiers_storage_size_per_modifier(&tmp_modifiers);
- storage.buffer = alloca(storage.modifier_count * storage.size_per_modifier);
-
- evaltime = evaluate_time_fmodifiers(&storage, &tmp_modifiers, NULL, 0.0f, strip->strip_time);
-
- NlaBlendData blend = {
- .snapshot = snapshot,
- .mode = strip->blendmode,
- .influence = strip->influence,
- };
-
- /* Evaluate all the F-Curves in the action,
- * saving the relevant pointers to data that will need to be used. */
- for (fcu = strip->act->curves.first; fcu; fcu = fcu->next) {
- float value = 0.0f;
-
- /* check if this curve should be skipped */
- if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
- continue;
- }
- if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
- continue;
- }
- if (BKE_fcurve_is_empty(fcu)) {
- continue;
- }
-
- /* evaluate the F-Curve's value for the time given in the strip
- * NOTE: we use the modified time here, since strip's F-Curve Modifiers
- * are applied on top of this.
- */
- value = evaluate_fcurve(fcu, evaltime);
+ NlaEvalSnapshot strip_snapshot;
+ nlaeval_snapshot_init(&strip_snapshot, channels, NULL);
- /* apply strip's F-Curve Modifiers on this value
- * NOTE: we apply the strip's original evaluation time not the modified one
- * (as per standard F-Curve eval)
- */
- evaluate_value_fmodifiers(&storage, &tmp_modifiers, fcu, &value, strip->strip_time);
+ nlasnapshot_from_action(
+ ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, &strip_snapshot);
+ nlasnapshot_blend(
+ channels, snapshot, &strip_snapshot, strip->blendmode, strip->influence, snapshot);
- /* Get an NLA evaluation channel to work with,
- * and accumulate the evaluated value with the value(s)
- * stored in this channel if it has been used already. */
- NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
-
- nlaeval_blend_value(&blend, nec, fcu->array_index, value);
- }
-
- nlaeval_blend_flush(&blend);
+ nlaeval_snapshot_free_data(&strip_snapshot);
/* unlink this strip's modifiers from the parent's modifiers again */
nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
@@ -1988,8 +1861,13 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr,
nlastrip_evaluate(
ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, anim_eval_context, flush_to_original);
- /* accumulate temp-buffer and full-buffer, using the 'real' strip */
- nlaeval_snapshot_mix_and_free(channels, snapshot, &snapshot1, &snapshot2, nes->strip_time);
+ /** Replace \a snapshot2 NULL channels with base or default values so all channels blend. */
+ nlasnapshot_ensure_channels(channels, &snapshot2);
+ nlasnapshot_blend(
+ channels, &snapshot1, &snapshot2, NLASTRIP_MODE_REPLACE, nes->strip_time, snapshot);
+
+ nlaeval_snapshot_free_data(&snapshot1);
+ nlaeval_snapshot_free_data(&snapshot2);
/* unlink this strip's modifiers from the parent's modifiers again */
nlaeval_fmodifiers_split_stacks(&nes->strip->modifiers, modifiers);
@@ -2099,12 +1977,21 @@ void nladata_flush_channels(PointerRNA *ptr,
/* for each channel with accumulated values, write its value on the property it affects */
LISTBASE_FOREACH (NlaEvalChannel *, nec, &channels->channels) {
+ /**
+ * The bitmask is set for all channels touched by NLA due to the domain() function.
+ * Channels touched by current set of evaluated strips will have a snapshot channel directly
+ * from the evaluation snapshot.
+ *
+ * This function falls back to the default value if the snapshot channel doesn't exist.
+ * Thus channels, touched by NLA but not by the current set of evaluated strips, will be
+ * reset to default. If channel not touched by NLA then it's value is unchanged.
+ */
NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(snapshot, nec);
PathResolvedRNA rna = {nec->key.ptr, nec->key.prop, -1};
for (int i = 0; i < nec_snapshot->length; i++) {
- if (BLI_BITMAP_TEST(nec->valid.ptr, i)) {
+ if (BLI_BITMAP_TEST(nec->domain.ptr, i)) {
float value = nec_snapshot->values[i];
if (nec->is_array) {
rna.prop_index = i;
@@ -2131,13 +2018,7 @@ static void nla_eval_domain_action(PointerRNA *ptr,
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
/* check if this curve should be skipped */
- if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
- continue;
- }
- if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
- continue;
- }
- if (BKE_fcurve_is_empty(fcu)) {
+ if (!is_fcurve_evaluatable(fcu)) {
continue;
}
@@ -2146,14 +2027,14 @@ static void nla_eval_domain_action(PointerRNA *ptr,
if (nec != NULL) {
/* For quaternion properties, enable all sub-channels. */
if (nec->mix_mode == NEC_MIX_QUATERNION) {
- BLI_bitmap_set_all(nec->valid.ptr, true, 4);
+ BLI_bitmap_set_all(nec->domain.ptr, true, 4);
continue;
}
int idx = nlaevalchan_validate_index(nec, fcu->array_index);
if (idx >= 0) {
- BLI_BITMAP_ENABLE(nec->valid.ptr, idx);
+ BLI_BITMAP_ENABLE(nec->domain.ptr, idx);
}
}
}
@@ -2212,190 +2093,345 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels,
/* ---------------------- */
+/** Tweaked strip is evaluated differently from other strips. Adjacent strips are ignored
+ * and includes a workaround for when user is not editing in place. */
+static void animsys_create_tweak_strip(const AnimData *adt,
+ const bool keyframing_to_strip,
+ NlaStrip *r_tweak_strip)
+
+{
+ /* Copy active strip so we can modify how it evaluates without affecting user data. */
+ memcpy(r_tweak_strip, adt->actstrip, sizeof(NlaStrip));
+ r_tweak_strip->next = r_tweak_strip->prev = NULL;
+
+ /* If tweaked strip is syncing action length, then evaluate using action length. */
+ if (r_tweak_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH) {
+ BKE_nlastrip_recalculate_bounds_sync_action(r_tweak_strip);
+ }
+
+ /* Strips with a user-defined time curve don't get properly remapped for editing
+ * at the moment, so mapping them just for display may be confusing. */
+ const bool is_inplace_tweak = !(adt->flag & ADT_NLA_EDIT_NOMAP) &&
+ !(adt->actstrip->flag & NLASTRIP_FLAG_USR_TIME);
+
+ if (!is_inplace_tweak) {
+ /* Use Hold due to no proper remapping yet (the note above). */
+ r_tweak_strip->extendmode = NLASTRIP_EXTEND_HOLD;
+
+ /* Disable range. */
+ r_tweak_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
+ }
+
+ /** Controls whether able to keyframe outside range of tweaked strip. */
+ if (keyframing_to_strip) {
+ r_tweak_strip->extendmode = (is_inplace_tweak &&
+ !(r_tweak_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) ?
+ NLASTRIP_EXTEND_NOTHING :
+ NLASTRIP_EXTEND_HOLD;
+ }
+}
+
+/** Action track and strip are associated with the non-pushed action. */
+static void animsys_create_action_track_strip(const AnimData *adt,
+ const bool keyframing_to_strip,
+ NlaStrip *r_action_strip)
+{
+ memset(r_action_strip, 0, sizeof(NlaStrip));
+
+ bAction *action = adt->action;
+
+ if ((adt->flag & ADT_NLA_EDIT_ON)) {
+ action = adt->tmpact;
+ }
+
+ /* Set settings of dummy NLA strip from AnimData settings. */
+ r_action_strip->act = action;
+
+ /* Action range is calculated taking F-Modifiers into account
+ * (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->actstart + 1.0f) :
+ (r_action_strip->actend);
+
+ r_action_strip->blendmode = adt->act_blendmode;
+ r_action_strip->extendmode = adt->act_extendmode;
+ r_action_strip->influence = adt->act_influence;
+
+ /* NOTE: must set this, or else the default setting overrides,
+ * and this setting doesn't work. */
+ r_action_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
+
+ /* Unless extendmode is Nothing (might be useful for flattening NLA evaluation), disable range.
+ * Extendmode Nothing and Hold will behave as normal. Hold Forward will behave just like Hold.
+ */
+ if (r_action_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+ r_action_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
+ }
+
+ const bool tweaking = (adt->flag & ADT_NLA_EDIT_ON) != 0;
+ const bool soloing = (adt->flag & ADT_NLA_SOLO_TRACK) != 0;
+ const bool actionstrip_evaluated = r_action_strip->act && !soloing && !tweaking;
+ if (!actionstrip_evaluated) {
+ r_action_strip->flag |= NLASTRIP_FLAG_MUTED;
+ }
+
+ /** If we're keyframing, then we must allow keyframing outside fcurve bounds. */
+ if (keyframing_to_strip) {
+ r_action_strip->extendmode = NLASTRIP_EXTEND_HOLD;
+ }
+}
+
+static bool is_nlatrack_evaluatable(const AnimData *adt, const NlaTrack *nlt)
+{
+ /* Skip disabled tracks unless it contains the tweaked strip. */
+ const bool contains_tweak_strip = (adt->flag & ADT_NLA_EDIT_ON) &&
+ (nlt->index == adt->act_track->index);
+ if ((nlt->flag & NLATRACK_DISABLED) && !contains_tweak_strip) {
+ return false;
+ }
+
+ /* Solo and muting are mutually exclusive. */
+ if (adt->flag & ADT_NLA_SOLO_TRACK) {
+ /* Skip if there is a solo track, but this isn't it. */
+ if ((nlt->flag & NLATRACK_SOLO) == 0) {
+ return false;
+ }
+ }
+ else {
+ /* Skip track if muted. */
+ if (nlt->flag & NLATRACK_MUTED) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/** Check for special case of non-pushed action being evaluated with no NLA influence (off and no
+ * strips evaluated) nor NLA interference (ensure NLA not soloing). */
+static bool is_action_track_evaluated_without_nla(const AnimData *adt,
+ const bool any_strip_evaluated)
+{
+ if (adt->action == NULL) {
+ return false;
+ }
+
+ if (any_strip_evaluated) {
+ return false;
+ }
+
+ /** NLA settings interference. */
+ if ((adt->flag & (ADT_NLA_SOLO_TRACK | ADT_NLA_EDIT_ON)) != 0) {
+ return false;
+ }
+
+ /** Allow action track to evaluate as if there isn't any NLA data. */
+ return true;
+}
+
/**
- * NLA Evaluation function - values are calculated and stored in temporary "NlaEvalChannels"
+ * XXX(Wayde Moss): #BKE_nlatrack_find_tweaked() exists within nla.c, but it doesn't appear to
+ * work as expected. From #animsys_evaluate_nla_for_flush(), it returns NULL in tweak mode. I'm not
+ * sure why. Preferably, it would be as simple as checking for `(adt->act_Track == nlt)` but that
+ * doesn't work either, neither does comparing indices.
*
+ * This function is a temporary work around. The first disabled track is always the tweaked track.
+ */
+static NlaTrack *nlatrack_find_tweaked(const AnimData *adt)
+{
+ NlaTrack *nlt;
+
+ if (adt == NULL) {
+ return NULL;
+ }
+
+ /* Since the track itself gets disabled, we want the first disabled. */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ if (nlt->flag & NLATRACK_DISABLED) {
+ return nlt;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * NLA Evaluation function - values are calculated and stored in temporary "NlaEvalChannels"
* \param[out] echannels: Evaluation channels with calculated values
- * \param[out] r_context: If not NULL,
- * data about the currently edited strip is stored here and excluded from value calculation.
- * \return false if NLA evaluation isn't actually applicable.
*/
-static bool animsys_evaluate_nla(NlaEvalData *echannels,
- PointerRNA *ptr,
- AnimData *adt,
- const AnimationEvalContext *anim_eval_context,
- const bool flush_to_original,
- NlaKeyframingContext *r_context)
+static bool animsys_evaluate_nla_for_flush(NlaEvalData *echannels,
+ PointerRNA *ptr,
+ const AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
NlaTrack *nlt;
short track_index = 0;
bool has_strips = false;
-
ListBase estrips = {NULL, NULL};
NlaEvalStrip *nes;
- NlaStrip dummy_strip_buf;
- /* dummy strip for active action */
- NlaStrip *dummy_strip = r_context ? &r_context->strip : &dummy_strip_buf;
+ NlaStrip tweak_strip;
- memset(dummy_strip, 0, sizeof(*dummy_strip));
+ NlaTrack *tweaked_track = nlatrack_find_tweaked(adt);
- /* 1. get the stack of strips to evaluate at current time (influence calculated here) */
+ /* Get the stack of strips to evaluate at current time (influence calculated here). */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
- /* stop here if tweaking is on and this strip is the tweaking track
- * (it will be the first one that's 'disabled')... */
- if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED)) {
- break;
+
+ if (!is_nlatrack_evaluatable(adt, nlt)) {
+ continue;
}
- /* solo and muting are mutually exclusive... */
- if (adt->flag & ADT_NLA_SOLO_TRACK) {
- /* skip if there is a solo track, but this isn't it */
- if ((nlt->flag & NLATRACK_SOLO) == 0) {
- continue;
- }
- /* else - mute doesn't matter */
+ if (nlt->strips.first) {
+ has_strips = true;
+ }
+
+ /** Append strip to evaluate for this track. */
+ if (nlt == tweaked_track) {
+ /** Tweaked strip is evaluated differently. */
+ animsys_create_tweak_strip(adt, false, &tweak_strip);
+ nes = nlastrips_ctime_get_strip_single(
+ &estrips, &tweak_strip, anim_eval_context, flush_to_original);
}
else {
- /* no solo tracks - skip track if muted */
- if (nlt->flag & NLATRACK_MUTED) {
- continue;
- }
+ nes = nlastrips_ctime_get_strip(
+ &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
+ }
+ if (nes) {
+ nes->track = nlt;
+ }
+ }
+
+ if (is_action_track_evaluated_without_nla(adt, has_strips)) {
+ BLI_freelistN(&estrips);
+ return false;
+ }
+
+ NlaStrip action_strip = {0};
+ animsys_create_action_track_strip(adt, false, &action_strip);
+ nlastrips_ctime_get_strip_single(&estrips, &action_strip, anim_eval_context, flush_to_original);
+
+ /* Per strip, evaluate and accumulate on top of existing channels. */
+ for (nes = estrips.first; nes; nes = nes->next) {
+ nlastrip_evaluate(ptr,
+ echannels,
+ NULL,
+ nes,
+ &echannels->eval_snapshot,
+ anim_eval_context,
+ flush_to_original);
+ }
+
+ /* Free temporary evaluation data that's not used elsewhere. */
+ BLI_freelistN(&estrips);
+ return true;
+}
+
+/** Lower blended values are calculated and accumulated into r_context->lower_eval_data. */
+static void animsys_evaluate_nla_for_keyframing(PointerRNA *ptr,
+ const AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ NlaKeyframingContext *r_context)
+{
+ if (!r_context) {
+ return;
+ }
+
+ /* Early out. If NLA track is soloing and tweaked action isn't it, then don't allow keyframe
+ * insertion. */
+ if (adt->flag & ADT_NLA_SOLO_TRACK) {
+ if (!(adt->act_track && (adt->act_track->flag & NLATRACK_SOLO))) {
+ r_context->eval_strip = NULL;
+ return;
+ }
+ }
+
+ NlaTrack *nlt;
+ short track_index = 0;
+ bool has_strips = false;
+
+ ListBase lower_estrips = {NULL, NULL};
+ NlaEvalStrip *nes;
+
+ NlaTrack *tweaked_track = nlatrack_find_tweaked(adt);
+
+ /* Get the lower stack of strips to evaluate at current time (influence calculated here). */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
+
+ if (!is_nlatrack_evaluatable(adt, nlt)) {
+ continue;
+ }
+
+ /* Tweaked strip effect should not be stored in any snapshot. */
+ if (nlt == tweaked_track) {
+ break;
}
- /* if this track has strips (but maybe they won't be suitable), set has_strips
- * - used for mainly for still allowing normal action evaluation...
- */
if (nlt->strips.first) {
has_strips = true;
}
- /* otherwise, get strip to evaluate for this channel */
+ /* Get strip to evaluate for this channel. */
nes = nlastrips_ctime_get_strip(
- &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
+ &lower_estrips, &nlt->strips, track_index, anim_eval_context, false);
if (nes) {
nes->track = nlt;
}
}
- /* add 'active' Action (may be tweaking track) as last strip to evaluate in NLA stack
- * - only do this if we're not exclusively evaluating the 'solo' NLA-track
- * - however, if the 'solo' track houses the current 'tweaking' strip,
- * then we should allow this to play, otherwise nothing happens
+ /** Note: Although we early out, we can still keyframe to the non-pushed action since the
+ * keyframe remap function detects (r_context->strip.act == NULL) and will keyframe without
+ * remapping.
*/
- if ((adt->action) && ((adt->flag & ADT_NLA_SOLO_TRACK) == 0 || (adt->flag & ADT_NLA_EDIT_ON))) {
- /* if there are strips, evaluate action as per NLA rules */
- if ((has_strips) || (adt->actstrip)) {
- /* make dummy NLA strip, and add that to the stack */
- ListBase dummy_trackslist;
-
- dummy_trackslist.first = dummy_trackslist.last = dummy_strip;
-
- /* Strips with a user-defined time curve don't get properly remapped for editing
- * at the moment, so mapping them just for display may be confusing. */
- bool is_inplace_tweak = (nlt) && !(adt->flag & ADT_NLA_EDIT_NOMAP) &&
- !(adt->actstrip->flag & NLASTRIP_FLAG_USR_TIME);
-
- if (is_inplace_tweak) {
- /* edit active action in-place according to its active strip, so copy the data */
- memcpy(dummy_strip, adt->actstrip, sizeof(NlaStrip));
- /* Prevents nla eval from considering active strip's adj strips.
- * For user, this means entering tweak mode on a strip ignores evaluating adjacent strips
- * in the same track. */
- dummy_strip->next = dummy_strip->prev = NULL;
-
- /* If tweaked strip is syncing action length, then evaluate using action length. */
- if (dummy_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH) {
- BKE_nlastrip_recalculate_bounds_sync_action(dummy_strip);
- }
- }
- else {
- /* set settings of dummy NLA strip from AnimData settings */
- dummy_strip->act = adt->action;
-
- /* action range is calculated taking F-Modifiers into account
- * (which making new strips doesn't do due to the troublesome nature of that) */
- calc_action_range(dummy_strip->act, &dummy_strip->actstart, &dummy_strip->actend, 1);
- dummy_strip->start = dummy_strip->actstart;
- dummy_strip->end = (IS_EQF(dummy_strip->actstart, dummy_strip->actend)) ?
- (dummy_strip->actstart + 1.0f) :
- (dummy_strip->actend);
-
- /* Always use the blend mode of the strip in tweak mode, even if not in-place. */
- if (nlt && adt->actstrip) {
- dummy_strip->blendmode = adt->actstrip->blendmode;
- dummy_strip->extendmode = NLASTRIP_EXTEND_HOLD;
- }
- else {
- dummy_strip->blendmode = adt->act_blendmode;
- dummy_strip->extendmode = adt->act_extendmode;
- }
+ if (is_action_track_evaluated_without_nla(adt, has_strips)) {
+ BLI_freelistN(&lower_estrips);
+ return;
+ }
- /* Unless extend-mode is Nothing (might be useful for flattening NLA evaluation),
- * disable range. */
- if (dummy_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
- dummy_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
- }
+ /* Write r_context->eval_strip. */
+ if (adt->flag & ADT_NLA_EDIT_ON) {
- dummy_strip->influence = adt->act_influence;
+ NlaStrip *tweak_strip = &r_context->strip;
+ animsys_create_tweak_strip(adt, true, tweak_strip);
+ r_context->eval_strip = nlastrips_ctime_get_strip_single(
+ NULL, tweak_strip, anim_eval_context, false);
+ }
+ else {
- /* NOTE: must set this, or else the default setting overrides,
- * and this setting doesn't work. */
- dummy_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
- }
+ NlaStrip *action_strip = &r_context->strip;
+ animsys_create_action_track_strip(adt, true, action_strip);
+ r_context->eval_strip = nlastrips_ctime_get_strip_single(
+ NULL, action_strip, anim_eval_context, false);
+ }
- /* add this to our list of evaluation strips */
- if (r_context == NULL) {
- nlastrips_ctime_get_strip(
- &estrips, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
- }
- /* If computing the context for keyframing, store data there instead of the list. */
- else {
- /* The extend mode here effectively controls
- * whether it is possible to key-frame beyond the ends.*/
- dummy_strip->extendmode = (is_inplace_tweak &&
- !(dummy_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) ?
- NLASTRIP_EXTEND_NOTHING :
- NLASTRIP_EXTEND_HOLD;
-
- r_context->eval_strip = nes = nlastrips_ctime_get_strip(
- NULL, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
-
- /* These setting combinations require no data from strips below, so exit immediately. */
- if ((nes == NULL) ||
- (dummy_strip->blendmode == NLASTRIP_MODE_REPLACE && dummy_strip->influence == 1.0f)) {
- BLI_freelistN(&estrips);
- return true;
- }
- }
- }
- else {
- /* special case - evaluate as if there isn't any NLA data */
- BLI_freelistN(&estrips);
- return false;
- }
+ /* If NULL, then keyframing will fail. No need to do any more processing. */
+ if (!r_context->eval_strip) {
+ BLI_freelistN(&lower_estrips);
+ return;
}
- /* only continue if there are strips to evaluate */
- if (BLI_listbase_is_empty(&estrips)) {
- return true;
+ /* If tweak strip is full REPLACE, then lower strips not needed. */
+ if (r_context->strip.blendmode == NLASTRIP_MODE_REPLACE &&
+ IS_EQF(r_context->strip.influence, 1.0f)) {
+ BLI_freelistN(&lower_estrips);
+ return;
}
- /* 2. for each strip, evaluate then accumulate on top of existing channels,
- * but don't set values yet. */
- for (nes = estrips.first; nes; nes = nes->next) {
+ /* For each strip, evaluate then accumulate on top of existing channels. */
+ for (nes = lower_estrips.first; nes; nes = nes->next) {
nlastrip_evaluate(ptr,
- echannels,
+ &r_context->lower_eval_data,
NULL,
nes,
- &echannels->eval_snapshot,
+ &r_context->lower_eval_data.eval_snapshot,
anim_eval_context,
- flush_to_original);
+ false);
}
- /* 3. free temporary evaluation data that's not used elsewhere */
- BLI_freelistN(&estrips);
- return true;
+ /* Free temporary evaluation data that's not used elsewhere. */
+ BLI_freelistN(&lower_estrips);
}
/* NLA Evaluation function (mostly for use through do_animdata)
@@ -2412,7 +2448,7 @@ static void animsys_calculate_nla(PointerRNA *ptr,
nlaeval_init(&echannels);
/* evaluate the NLA stack, obtaining a set of values to flush */
- if (animsys_evaluate_nla(&echannels, ptr, adt, anim_eval_context, flush_to_original, NULL)) {
+ if (animsys_evaluate_nla_for_flush(&echannels, ptr, adt, anim_eval_context, flush_to_original)) {
/* reset any channels touched by currently inactive actions to default value */
animsys_evaluate_nla_domain(ptr, &echannels, adt);
@@ -2435,6 +2471,74 @@ static void animsys_calculate_nla(PointerRNA *ptr,
/* ---------------------- */
+void nlasnapshot_ensure_channels(NlaEvalData *eval_data, NlaEvalSnapshot *snapshot)
+{
+ LISTBASE_FOREACH (NlaEvalChannel *, nec, &eval_data->channels) {
+ nlaeval_snapshot_ensure_channel(snapshot, nec);
+ }
+}
+
+/** Blends the \a lower_snapshot with the \a upper_snapshot into \a r_blended_snapshot according
+ * to the given \a upper_blendmode and \a upper_influence. */
+void nlasnapshot_blend(NlaEvalData *eval_data,
+ NlaEvalSnapshot *lower_snapshot,
+ NlaEvalSnapshot *upper_snapshot,
+ const short upper_blendmode,
+ const float upper_influence,
+ NlaEvalSnapshot *r_blended_snapshot)
+{
+ nlaeval_snapshot_ensure_size(r_blended_snapshot, eval_data->num_channels);
+
+ const bool zero_upper_influence = IS_EQF(upper_influence, 0.0f);
+
+ LISTBASE_FOREACH (NlaEvalChannel *, nec, &eval_data->channels) {
+ const int length = nec->base_snapshot.length;
+
+ NlaEvalChannelSnapshot *upper_necs = nlaeval_snapshot_get(upper_snapshot, nec->index);
+ NlaEvalChannelSnapshot *lower_necs = nlaeval_snapshot_get(lower_snapshot, nec->index);
+ if (upper_necs == NULL && lower_necs == NULL) {
+ continue;
+ }
+
+ /** Blend with lower_snapshot's base or default. */
+ if (lower_necs == NULL) {
+ lower_necs = nlaeval_snapshot_find_channel(lower_snapshot->base, nec);
+ }
+
+ NlaEvalChannelSnapshot *result_necs = nlaeval_snapshot_ensure_channel(r_blended_snapshot, nec);
+
+ if (upper_necs == NULL || zero_upper_influence) {
+ memcpy(result_necs->values, lower_necs->values, length * sizeof(float));
+ continue;
+ }
+
+ if (upper_blendmode == NLASTRIP_MODE_COMBINE) {
+ const int mix_mode = nec->mix_mode;
+ if (mix_mode == NEC_MIX_QUATERNION) {
+ nla_combine_quaternion(
+ lower_necs->values, upper_necs->values, upper_influence, result_necs->values);
+ }
+ else {
+ for (int j = 0; j < length; j++) {
+ result_necs->values[j] = nla_combine_value(mix_mode,
+ nec->base_snapshot.values[j],
+ lower_necs->values[j],
+ upper_necs->values[j],
+ upper_influence);
+ }
+ }
+ }
+ else {
+ for (int j = 0; j < length; j++) {
+ result_necs->values[j] = nla_blend_value(
+ upper_blendmode, lower_necs->values[j], upper_necs->values[j], upper_influence);
+ }
+ }
+ }
+}
+
+/* ---------------------- */
+
/**
* Prepare data necessary to compute correct keyframe values for NLA strips
* with non-Replace mode or influence different from 1.
@@ -2448,8 +2552,7 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
struct ListBase *cache,
struct PointerRNA *ptr,
struct AnimData *adt,
- const AnimationEvalContext *anim_eval_context,
- const bool flush_to_original)
+ const AnimationEvalContext *anim_eval_context)
{
/* No remapping needed if NLA is off or no action. */
if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) ||
@@ -2472,8 +2575,7 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
ctx->adt = adt;
nlaeval_init(&ctx->lower_eval_data);
- animsys_evaluate_nla(
- &ctx->lower_eval_data, ptr, adt, anim_eval_context, flush_to_original, ctx);
+ animsys_evaluate_nla_for_keyframing(ptr, adt, anim_eval_context, ctx);
BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
BLI_addtail(cache, ctx);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 4c9fb4b191a..a59ead84aca 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -331,6 +331,8 @@ IDTypeInfo IDType_ID_AR = {
.blend_read_expand = armature_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/** \} */
@@ -1889,9 +1891,8 @@ void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
* bone loc/sca/rot is ignored, scene and frame are not used. */
BKE_pose_where_is_bone(depsgraph, NULL, ob, &work_pchan, 0.0f, false);
- /* find the matrix, need to remove the bone transforms first so this is
- * calculated as a matrix to set rather than a difference ontop of what's
- * already there. */
+ /* Find the matrix, need to remove the bone transforms first so this is calculated
+ * as a matrix to set rather than a difference on top of what's already there. */
unit_m4(outmat);
BKE_pchan_apply_mat4(&work_pchan, outmat, false);
@@ -1943,7 +1944,7 @@ void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float r_mat[3][3])
float quat[4];
/* NOTE: we now don't normalize the stored values anymore,
- * since this was kindof evil in some cases but if this proves to be too problematic,
+ * since this was kind of evil in some cases but if this proves to be too problematic,
* switch back to the old system of operating directly on the stored copy. */
normalize_qt_qt(quat, pchan->quat);
quat_to_mat3(r_mat, quat);
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 8c666597276..8f74b8ff054 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -428,8 +428,8 @@ static void splineik_evaluate_bone(
if (fabsf(scaleFac) != 0.0f) {
scale = 1.0f / fabsf(scaleFac);
- /* we need to clamp this within sensible values */
- /* NOTE: these should be fine for now, but should get sanitised in future */
+ /* We need to clamp this within sensible values. */
+ /* NOTE: these should be fine for now, but should get sanitized in future. */
CLAMP(scale, 0.0001f, 100000.0f);
}
else {
@@ -483,7 +483,7 @@ static void splineik_evaluate_bone(
final_scale = 1.0f;
}
- /* apply the scaling (assuming normalised scale) */
+ /* Apply the scaling (assuming normalized scale). */
mul_v3_fl(poseMat[0], final_scale);
mul_v3_fl(poseMat[2], final_scale);
break;
diff --git a/source/blender/blenkernel/intern/asset.c b/source/blender/blenkernel/intern/asset.cc
index 7ccb0aa2b57..89c3523285d 100644
--- a/source/blender/blenkernel/intern/asset.c
+++ b/source/blender/blenkernel/intern/asset.cc
@@ -20,6 +20,10 @@
#include <string.h>
+#include "DNA_ID.h"
+#include "DNA_asset_types.h"
+#include "DNA_defaults.h"
+
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
@@ -29,17 +33,13 @@
#include "BKE_icons.h"
#include "BKE_idprop.h"
-#include "DNA_ID.h"
-#include "DNA_asset_types.h"
-#include "DNA_defaults.h"
-
#include "BLO_read_write.h"
#include "MEM_guardedalloc.h"
AssetMetaData *BKE_asset_metadata_create(void)
{
- AssetMetaData *asset_data = MEM_callocN(sizeof(*asset_data), __func__);
+ AssetMetaData *asset_data = (AssetMetaData *)MEM_callocN(sizeof(*asset_data), __func__);
memcpy(asset_data, DNA_struct_default_get(AssetMetaData), sizeof(*asset_data));
return asset_data;
}
@@ -57,7 +57,7 @@ void BKE_asset_metadata_free(AssetMetaData **asset_data)
static AssetTag *asset_metadata_tag_add(AssetMetaData *asset_data, const char *const name)
{
- AssetTag *tag = MEM_callocN(sizeof(*tag), __func__);
+ AssetTag *tag = (AssetTag *)MEM_callocN(sizeof(*tag), __func__);
BLI_strncpy(tag->name, name, sizeof(tag->name));
BLI_addtail(&asset_data->tags, tag);
@@ -81,12 +81,12 @@ AssetTag *BKE_asset_metadata_tag_add(AssetMetaData *asset_data, const char *name
struct AssetTagEnsureResult BKE_asset_metadata_tag_ensure(AssetMetaData *asset_data,
const char *name)
{
- struct AssetTagEnsureResult result = {.tag = NULL};
+ struct AssetTagEnsureResult result = {nullptr};
if (!name[0]) {
return result;
}
- AssetTag *tag = BLI_findstring(&asset_data->tags, name, offsetof(AssetTag, name));
+ AssetTag *tag = (AssetTag *)BLI_findstring(&asset_data->tags, name, offsetof(AssetTag, name));
if (tag) {
result.tag = tag;
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index e1e8d06b9ec..378fdfd27f2 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -17,6 +17,7 @@
#include <utility>
#include "BKE_attribute_access.hh"
+#include "BKE_attribute_math.hh"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_geometry_set.hh"
@@ -323,29 +324,47 @@ template<typename T> class ArrayReadAttribute final : public ReadAttribute {
}
};
-template<typename StructT, typename ElemT, typename GetFuncT, typename SetFuncT>
+template<typename T> class OwnedArrayReadAttribute final : public ReadAttribute {
+ private:
+ Array<T> data_;
+
+ public:
+ OwnedArrayReadAttribute(AttributeDomain domain, Array<T> data)
+ : ReadAttribute(domain, CPPType::get<T>(), data.size()), data_(std::move(data))
+ {
+ }
+
+ void get_internal(const int64_t index, void *r_value) const override
+ {
+ new (r_value) T(data_[index]);
+ }
+
+ void initialize_span() const override
+ {
+ /* The data will not be modified, so this const_cast is fine. */
+ array_buffer_ = const_cast<T *>(data_.data());
+ array_is_temporary_ = false;
+ }
+};
+
+template<typename StructT,
+ typename ElemT,
+ ElemT (*GetFunc)(const StructT &),
+ void (*SetFunc)(StructT &, const ElemT &)>
class DerivedArrayWriteAttribute final : public WriteAttribute {
private:
MutableSpan<StructT> data_;
- GetFuncT get_function_;
- SetFuncT set_function_;
public:
- DerivedArrayWriteAttribute(AttributeDomain domain,
- MutableSpan<StructT> data,
- GetFuncT get_function,
- SetFuncT set_function)
- : WriteAttribute(domain, CPPType::get<ElemT>(), data.size()),
- data_(data),
- get_function_(std::move(get_function)),
- set_function_(std::move(set_function))
+ DerivedArrayWriteAttribute(AttributeDomain domain, MutableSpan<StructT> data)
+ : WriteAttribute(domain, CPPType::get<ElemT>(), data.size()), data_(data)
{
}
void get_internal(const int64_t index, void *r_value) const override
{
const StructT &struct_value = data_[index];
- const ElemT value = get_function_(struct_value);
+ const ElemT value = GetFunc(struct_value);
new (r_value) ElemT(value);
}
@@ -353,28 +372,25 @@ class DerivedArrayWriteAttribute final : public WriteAttribute {
{
StructT &struct_value = data_[index];
const ElemT &typed_value = *reinterpret_cast<const ElemT *>(value);
- set_function_(struct_value, typed_value);
+ SetFunc(struct_value, typed_value);
}
};
-template<typename StructT, typename ElemT, typename GetFuncT>
+template<typename StructT, typename ElemT, ElemT (*GetFunc)(const StructT &)>
class DerivedArrayReadAttribute final : public ReadAttribute {
private:
Span<StructT> data_;
- GetFuncT get_function_;
public:
- DerivedArrayReadAttribute(AttributeDomain domain, Span<StructT> data, GetFuncT get_function)
- : ReadAttribute(domain, CPPType::get<ElemT>(), data.size()),
- data_(data),
- get_function_(std::move(get_function))
+ DerivedArrayReadAttribute(AttributeDomain domain, Span<StructT> data)
+ : ReadAttribute(domain, CPPType::get<ElemT>(), data.size()), data_(data)
{
}
void get_internal(const int64_t index, void *r_value) const override
{
const StructT &struct_value = data_[index];
- const ElemT value = get_function_(struct_value);
+ const ElemT value = GetFunc(struct_value);
new (r_value) ElemT(value);
}
};
@@ -492,133 +508,835 @@ CustomDataType cpp_type_to_custom_data_type(const blender::fn::CPPType &type)
return static_cast<CustomDataType>(-1);
}
-} // namespace blender::bke
+/**
+ * A #BuiltinAttributeProvider is responsible for exactly one attribute on a geometry component.
+ * The attribute is identified by its name and has a fixed domain and type. Builtin attributes do
+ * not follow the same loose rules as other attributes, because they are mapped to internal
+ * "legacy" data structures. For example, some builtin attributes cannot be deleted. */
+class BuiltinAttributeProvider {
+ public:
+ /* Some utility enums to avoid hard to read booleans in function calls. */
+ enum CreatableEnum {
+ Creatable,
+ NonCreatable,
+ };
+ enum WritableEnum {
+ Writable,
+ Readonly,
+ };
+ enum DeletableEnum {
+ Deletable,
+ NonDeletable,
+ };
-/* -------------------------------------------------------------------- */
-/** \name Utilities for Accessing Attributes
- * \{ */
+ protected:
+ const std::string name_;
+ const AttributeDomain domain_;
+ const CustomDataType data_type_;
+ const CreatableEnum createable_;
+ const WritableEnum writable_;
+ const DeletableEnum deletable_;
-static ReadAttributePtr read_attribute_from_custom_data(const CustomData &custom_data,
- const int size,
- const StringRef attribute_name,
- const AttributeDomain domain)
-{
- using namespace blender;
- using namespace blender::bke;
- for (const CustomDataLayer &layer : Span(custom_data.layers, custom_data.totlayer)) {
- if (layer.name != nullptr && layer.name == attribute_name) {
- switch (layer.type) {
+ public:
+ BuiltinAttributeProvider(std::string name,
+ const AttributeDomain domain,
+ const CustomDataType data_type,
+ const CreatableEnum createable,
+ const WritableEnum writable,
+ const DeletableEnum deletable)
+ : name_(std::move(name)),
+ domain_(domain),
+ data_type_(data_type),
+ createable_(createable),
+ writable_(writable),
+ deletable_(deletable)
+ {
+ }
+
+ virtual ReadAttributePtr try_get_for_read(const GeometryComponent &component) const = 0;
+ virtual WriteAttributePtr try_get_for_write(GeometryComponent &component) const = 0;
+ virtual bool try_delete(GeometryComponent &component) const = 0;
+ virtual bool try_create(GeometryComponent &UNUSED(component)) const = 0;
+ virtual bool exists(const GeometryComponent &component) const = 0;
+
+ StringRefNull name() const
+ {
+ return name_;
+ }
+
+ AttributeDomain domain() const
+ {
+ return domain_;
+ }
+
+ CustomDataType data_type() const
+ {
+ return data_type_;
+ }
+};
+
+/**
+ * A #DynamicAttributesProvider manages a set of named attributes on a geometry component. Each
+ * attribute has a name, domain and type.
+ */
+class DynamicAttributesProvider {
+ public:
+ virtual ReadAttributePtr try_get_for_read(const GeometryComponent &component,
+ const StringRef attribute_name) const = 0;
+ virtual WriteAttributePtr try_get_for_write(GeometryComponent &component,
+ const StringRef attribute_name) const = 0;
+ virtual bool try_delete(GeometryComponent &component, const StringRef attribute_name) const = 0;
+ virtual bool try_create(GeometryComponent &UNUSED(component),
+ const StringRef UNUSED(attribute_name),
+ const AttributeDomain UNUSED(domain),
+ const CustomDataType UNUSED(data_type)) const
+ {
+ /* Some providers should not create new attributes. */
+ return false;
+ };
+
+ virtual void list(const GeometryComponent &component, Set<std::string> &r_names) const = 0;
+ virtual void supported_domains(Vector<AttributeDomain> &r_domains) const = 0;
+};
+
+/**
+ * Utility to group together multiple functions that are used to access custom data on geometry
+ * components in a generic way.
+ */
+struct CustomDataAccessInfo {
+ using CustomDataGetter = CustomData *(*)(GeometryComponent &component);
+ using ConstCustomDataGetter = const CustomData *(*)(const GeometryComponent &component);
+ using UpdateCustomDataPointers = void (*)(GeometryComponent &component);
+
+ CustomDataGetter get_custom_data;
+ ConstCustomDataGetter get_const_custom_data;
+ UpdateCustomDataPointers update_custom_data_pointers;
+};
+
+/**
+ * This provider is used to provide access to builtin attributes. It supports making internal types
+ * available as different types. For example, the vertex position attribute is stored as part of
+ * the #MVert struct, but is exposed as float3 attribute.
+ */
+class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
+ using AsReadAttribute = ReadAttributePtr (*)(const void *data, const int domain_size);
+ using AsWriteAttribute = WriteAttributePtr (*)(void *data, const int domain_size);
+ const CustomDataType stored_type_;
+ const CustomDataAccessInfo custom_data_access_;
+ const AsReadAttribute as_read_attribute_;
+ const AsWriteAttribute as_write_attribute_;
+
+ public:
+ BuiltinCustomDataLayerProvider(std::string attribute_name,
+ const AttributeDomain domain,
+ const CustomDataType attribute_type,
+ const CustomDataType stored_type,
+ const CreatableEnum creatable,
+ const WritableEnum writable,
+ const DeletableEnum deletable,
+ const CustomDataAccessInfo custom_data_access,
+ const AsReadAttribute as_read_attribute,
+ const AsWriteAttribute as_write_attribute)
+ : BuiltinAttributeProvider(
+ std::move(attribute_name), domain, attribute_type, creatable, writable, deletable),
+ stored_type_(stored_type),
+ custom_data_access_(custom_data_access),
+ as_read_attribute_(as_read_attribute),
+ as_write_attribute_(as_write_attribute)
+ {
+ }
+
+ ReadAttributePtr try_get_for_read(const GeometryComponent &component) const final
+ {
+ const CustomData *custom_data = custom_data_access_.get_const_custom_data(component);
+ if (custom_data == nullptr) {
+ return {};
+ }
+ const int domain_size = component.attribute_domain_size(domain_);
+ const void *data = CustomData_get_layer(custom_data, stored_type_);
+ if (data == nullptr) {
+ return {};
+ }
+ return as_read_attribute_(data, domain_size);
+ }
+
+ WriteAttributePtr try_get_for_write(GeometryComponent &component) const final
+ {
+ if (writable_ != Writable) {
+ return {};
+ }
+ CustomData *custom_data = custom_data_access_.get_custom_data(component);
+ if (custom_data == nullptr) {
+ return {};
+ }
+ const int domain_size = component.attribute_domain_size(domain_);
+ void *data = CustomData_get_layer(custom_data, stored_type_);
+ if (data == nullptr) {
+ return {};
+ }
+ void *new_data = CustomData_duplicate_referenced_layer(custom_data, stored_type_, domain_size);
+ if (data != new_data) {
+ custom_data_access_.update_custom_data_pointers(component);
+ data = new_data;
+ }
+ return as_write_attribute_(data, domain_size);
+ }
+
+ bool try_delete(GeometryComponent &component) const final
+ {
+ if (deletable_ != Deletable) {
+ return false;
+ }
+ CustomData *custom_data = custom_data_access_.get_custom_data(component);
+ if (custom_data == nullptr) {
+ return {};
+ }
+
+ const int domain_size = component.attribute_domain_size(domain_);
+ const int layer_index = CustomData_get_layer_index(custom_data, stored_type_);
+ const bool delete_success = CustomData_free_layer(
+ custom_data, stored_type_, domain_size, layer_index);
+ if (delete_success) {
+ custom_data_access_.update_custom_data_pointers(component);
+ }
+ return delete_success;
+ }
+
+ bool try_create(GeometryComponent &component) const final
+ {
+ if (createable_ != Creatable) {
+ return false;
+ }
+ CustomData *custom_data = custom_data_access_.get_custom_data(component);
+ if (custom_data == nullptr) {
+ return false;
+ }
+ if (CustomData_get_layer(custom_data, stored_type_) != nullptr) {
+ /* Exists already. */
+ return false;
+ }
+ const int domain_size = component.attribute_domain_size(domain_);
+ const void *data = CustomData_add_layer(
+ custom_data, stored_type_, CD_DEFAULT, nullptr, domain_size);
+ const bool success = data != nullptr;
+ if (success) {
+ custom_data_access_.update_custom_data_pointers(component);
+ }
+ return success;
+ }
+
+ bool exists(const GeometryComponent &component) const final
+ {
+ const CustomData *custom_data = custom_data_access_.get_const_custom_data(component);
+ if (custom_data == nullptr) {
+ return false;
+ }
+ const void *data = CustomData_get_layer(custom_data, stored_type_);
+ return data != nullptr;
+ }
+};
+
+/**
+ * This is the attribute provider for most user generated attributes.
+ */
+class CustomDataAttributeProvider 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;
+ const AttributeDomain domain_;
+ const CustomDataAccessInfo custom_data_access_;
+
+ public:
+ CustomDataAttributeProvider(const AttributeDomain domain,
+ const CustomDataAccessInfo custom_data_access)
+ : domain_(domain), custom_data_access_(custom_data_access)
+ {
+ }
+
+ ReadAttributePtr try_get_for_read(const GeometryComponent &component,
+ const StringRef attribute_name) const final
+ {
+ const CustomData *custom_data = custom_data_access_.get_const_custom_data(component);
+ if (custom_data == nullptr) {
+ return {};
+ }
+ const int domain_size = component.attribute_domain_size(domain_);
+ for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) {
+ if (layer.name != attribute_name) {
+ continue;
+ }
+ const CustomDataType data_type = (CustomDataType)layer.type;
+ switch (data_type) {
case CD_PROP_FLOAT:
- return std::make_unique<ArrayReadAttribute<float>>(
- domain, Span(static_cast<float *>(layer.data), size));
+ return this->layer_to_read_attribute<float>(layer, domain_size);
case CD_PROP_FLOAT2:
- return std::make_unique<ArrayReadAttribute<float2>>(
- domain, Span(static_cast<float2 *>(layer.data), size));
+ return this->layer_to_read_attribute<float2>(layer, domain_size);
case CD_PROP_FLOAT3:
- return std::make_unique<ArrayReadAttribute<float3>>(
- domain, Span(static_cast<float3 *>(layer.data), size));
+ return this->layer_to_read_attribute<float3>(layer, domain_size);
case CD_PROP_INT32:
- return std::make_unique<ArrayReadAttribute<int>>(
- domain, Span(static_cast<int *>(layer.data), size));
+ return this->layer_to_read_attribute<int>(layer, domain_size);
case CD_PROP_COLOR:
- return std::make_unique<ArrayReadAttribute<Color4f>>(
- domain, Span(static_cast<Color4f *>(layer.data), size));
+ return this->layer_to_read_attribute<Color4f>(layer, domain_size);
case CD_PROP_BOOL:
- return std::make_unique<ArrayReadAttribute<bool>>(
- domain, Span(static_cast<bool *>(layer.data), size));
+ return this->layer_to_read_attribute<bool>(layer, domain_size);
+ default:
+ break;
}
}
+ return {};
}
- return {};
-}
-
-static WriteAttributePtr write_attribute_from_custom_data(
- CustomData &custom_data,
- const int size,
- const StringRef attribute_name,
- const AttributeDomain domain,
- const std::function<void()> &update_customdata_pointers)
-{
- using namespace blender;
- using namespace blender::bke;
- for (const CustomDataLayer &layer : Span(custom_data.layers, custom_data.totlayer)) {
- if (layer.name != nullptr && layer.name == attribute_name) {
- const void *data_before = layer.data;
- /* The data layer might be shared with someone else. Since the caller wants to modify it, we
- * copy it first. */
- CustomData_duplicate_referenced_layer_named(&custom_data, layer.type, layer.name, size);
- if (data_before != layer.data) {
- update_customdata_pointers();
+ WriteAttributePtr try_get_for_write(GeometryComponent &component,
+ const StringRef attribute_name) const final
+ {
+ CustomData *custom_data = custom_data_access_.get_custom_data(component);
+ if (custom_data == nullptr) {
+ return {};
+ }
+ const int domain_size = component.attribute_domain_size(domain_);
+ for (CustomDataLayer &layer : MutableSpan(custom_data->layers, custom_data->totlayer)) {
+ if (layer.name != attribute_name) {
+ continue;
}
- switch (layer.type) {
+ CustomData_duplicate_referenced_layer_named(
+ custom_data, layer.type, layer.name, domain_size);
+ const CustomDataType data_type = (CustomDataType)layer.type;
+ switch (data_type) {
case CD_PROP_FLOAT:
- return std::make_unique<ArrayWriteAttribute<float>>(
- domain, MutableSpan(static_cast<float *>(layer.data), size));
+ return this->layer_to_write_attribute<float>(layer, domain_size);
case CD_PROP_FLOAT2:
- return std::make_unique<ArrayWriteAttribute<float2>>(
- domain, MutableSpan(static_cast<float2 *>(layer.data), size));
+ return this->layer_to_write_attribute<float2>(layer, domain_size);
case CD_PROP_FLOAT3:
- return std::make_unique<ArrayWriteAttribute<float3>>(
- domain, MutableSpan(static_cast<float3 *>(layer.data), size));
+ return this->layer_to_write_attribute<float3>(layer, domain_size);
case CD_PROP_INT32:
- return std::make_unique<ArrayWriteAttribute<int>>(
- domain, MutableSpan(static_cast<int *>(layer.data), size));
+ return this->layer_to_write_attribute<int>(layer, domain_size);
case CD_PROP_COLOR:
- return std::make_unique<ArrayWriteAttribute<Color4f>>(
- domain, MutableSpan(static_cast<Color4f *>(layer.data), size));
+ return this->layer_to_write_attribute<Color4f>(layer, domain_size);
case CD_PROP_BOOL:
- return std::make_unique<ArrayWriteAttribute<bool>>(
- domain, MutableSpan(static_cast<bool *>(layer.data), size));
+ return this->layer_to_write_attribute<bool>(layer, domain_size);
+ default:
+ break;
+ }
+ }
+ return {};
+ }
+
+ bool try_delete(GeometryComponent &component, const StringRef attribute_name) const final
+ {
+ CustomData *custom_data = custom_data_access_.get_custom_data(component);
+ if (custom_data == nullptr) {
+ return false;
+ }
+ const int domain_size = component.attribute_domain_size(domain_);
+ for (const int i : IndexRange(custom_data->totlayer)) {
+ const CustomDataLayer &layer = custom_data->layers[i];
+ if (this->type_is_supported((CustomDataType)layer.type) && layer.name == attribute_name) {
+ CustomData_free_layer(custom_data, layer.type, domain_size, i);
+ return true;
}
}
+ return false;
}
- return {};
+
+ bool try_create(GeometryComponent &component,
+ const StringRef attribute_name,
+ const AttributeDomain domain,
+ const CustomDataType data_type) const final
+ {
+ if (domain_ != domain) {
+ return false;
+ }
+ if (!this->type_is_supported(data_type)) {
+ return false;
+ }
+ CustomData *custom_data = custom_data_access_.get_custom_data(component);
+ if (custom_data == nullptr) {
+ return false;
+ }
+ for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) {
+ if (layer.name == attribute_name) {
+ return false;
+ }
+ }
+ const int domain_size = component.attribute_domain_size(domain_);
+ char attribute_name_c[MAX_NAME];
+ attribute_name.copy(attribute_name_c);
+ CustomData_add_layer_named(
+ custom_data, data_type, CD_DEFAULT, nullptr, domain_size, attribute_name_c);
+ return true;
+ }
+
+ void list(const GeometryComponent &component, Set<std::string> &r_names) const final
+ {
+ const CustomData *custom_data = custom_data_access_.get_const_custom_data(component);
+ if (custom_data == nullptr) {
+ return;
+ }
+ for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) {
+ if (this->type_is_supported((CustomDataType)layer.type)) {
+ r_names.add(layer.name);
+ }
+ }
+ }
+
+ void supported_domains(Vector<AttributeDomain> &r_domains) const final
+ {
+ r_domains.append_non_duplicates(domain_);
+ }
+
+ private:
+ template<typename T>
+ ReadAttributePtr layer_to_read_attribute(const CustomDataLayer &layer,
+ const int domain_size) const
+ {
+ return std::make_unique<ArrayReadAttribute<T>>(
+ domain_, Span(static_cast<const T *>(layer.data), domain_size));
+ }
+
+ template<typename T>
+ WriteAttributePtr layer_to_write_attribute(CustomDataLayer &layer, const int domain_size) const
+ {
+ return std::make_unique<ArrayWriteAttribute<T>>(
+ domain_, MutableSpan(static_cast<T *>(layer.data), domain_size));
+ }
+
+ bool type_is_supported(CustomDataType data_type) const
+ {
+ return ((1ULL << data_type) & supported_types_mask) != 0;
+ }
+};
+
+static Mesh *get_mesh_from_component_for_write(GeometryComponent &component)
+{
+ BLI_assert(component.type() == GeometryComponentType::Mesh);
+ MeshComponent &mesh_component = static_cast<MeshComponent &>(component);
+ return mesh_component.get_for_write();
}
-/* Returns true when the layer was found and is deleted. */
-static bool delete_named_custom_data_layer(CustomData &custom_data,
- const StringRef attribute_name,
- const int size)
+static const Mesh *get_mesh_from_component_for_read(const GeometryComponent &component)
{
- for (const int index : blender::IndexRange(custom_data.totlayer)) {
- const CustomDataLayer &layer = custom_data.layers[index];
- if (layer.name == attribute_name) {
- CustomData_free_layer(&custom_data, layer.type, size, index);
+ BLI_assert(component.type() == GeometryComponentType::Mesh);
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ return mesh_component.get_for_read();
+}
+
+/**
+ * This attribute provider makes uv maps available as float2 attributes.
+ */
+class MeshUVsAttributeProvider final : public DynamicAttributesProvider {
+ public:
+ ReadAttributePtr try_get_for_read(const GeometryComponent &component,
+ const StringRef attribute_name) const final
+ {
+ const Mesh *mesh = get_mesh_from_component_for_read(component);
+ if (mesh == nullptr) {
+ return {};
+ }
+ for (const CustomDataLayer &layer : Span(mesh->ldata.layers, mesh->ldata.totlayer)) {
+ if (layer.type == CD_MLOOPUV) {
+ if (layer.name == attribute_name) {
+ return std::make_unique<DerivedArrayReadAttribute<MLoopUV, float2, get_loop_uv>>(
+ ATTR_DOMAIN_CORNER, Span(static_cast<const MLoopUV *>(layer.data), mesh->totloop));
+ }
+ }
+ }
+ return {};
+ }
+
+ WriteAttributePtr try_get_for_write(GeometryComponent &component,
+ const StringRef attribute_name) const final
+ {
+ Mesh *mesh = get_mesh_from_component_for_write(component);
+ if (mesh == nullptr) {
+ return {};
+ }
+ for (CustomDataLayer &layer : MutableSpan(mesh->ldata.layers, mesh->ldata.totlayer)) {
+ if (layer.type == CD_MLOOPUV) {
+ if (layer.name == attribute_name) {
+ void *data_old = layer.data;
+ void *data_new = CustomData_duplicate_referenced_layer_named(
+ &mesh->ldata, CD_MLOOPUV, layer.name, mesh->totloop);
+ if (data_old != data_new) {
+ BKE_mesh_update_customdata_pointers(mesh, false);
+ }
+ return std::make_unique<
+ DerivedArrayWriteAttribute<MLoopUV, float2, get_loop_uv, set_loop_uv>>(
+ ATTR_DOMAIN_CORNER, MutableSpan(static_cast<MLoopUV *>(layer.data), mesh->totloop));
+ }
+ }
+ }
+ return {};
+ }
+
+ bool try_delete(GeometryComponent &component, const StringRef attribute_name) const final
+ {
+ Mesh *mesh = get_mesh_from_component_for_write(component);
+ if (mesh == nullptr) {
+ return false;
+ }
+ for (const int i : IndexRange(mesh->ldata.totlayer)) {
+ const CustomDataLayer &layer = mesh->ldata.layers[i];
+ if (layer.type == CD_MLOOPUV && layer.name == attribute_name) {
+ CustomData_free_layer(&mesh->ldata, CD_MLOOPUV, mesh->totloop, i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void list(const GeometryComponent &component, Set<std::string> &r_names) const final
+ {
+ const Mesh *mesh = get_mesh_from_component_for_read(component);
+ if (mesh == nullptr) {
+ return;
+ }
+ for (const CustomDataLayer &layer : Span(mesh->ldata.layers, mesh->ldata.totlayer)) {
+ if (layer.type == CD_MLOOPUV) {
+ r_names.add(layer.name);
+ }
+ }
+ }
+
+ void supported_domains(Vector<AttributeDomain> &r_domains) const final
+ {
+ r_domains.append_non_duplicates(ATTR_DOMAIN_CORNER);
+ }
+
+ private:
+ static float2 get_loop_uv(const MLoopUV &uv)
+ {
+ return float2(uv.uv);
+ }
+
+ static void set_loop_uv(MLoopUV &uv, const float2 &co)
+ {
+ copy_v2_v2(uv.uv, co);
+ }
+};
+
+/**
+ * This provider makes vertex groups available as float attributes.
+ */
+class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
+ public:
+ ReadAttributePtr try_get_for_read(const GeometryComponent &component,
+ const StringRef attribute_name) const final
+ {
+ BLI_assert(component.type() == GeometryComponentType::Mesh);
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ const Mesh *mesh = mesh_component.get_for_read();
+ const int vertex_group_index = mesh_component.vertex_group_names().lookup_default_as(
+ attribute_name, -1);
+ if (vertex_group_index < 0) {
+ return {};
+ }
+ if (mesh == nullptr || mesh->dvert == nullptr) {
+ static const float default_value = 0.0f;
+ return std::make_unique<ConstantReadAttribute>(
+ ATTR_DOMAIN_POINT, mesh->totvert, CPPType::get<float>(), &default_value);
+ }
+ return std::make_unique<VertexWeightReadAttribute>(
+ mesh->dvert, mesh->totvert, vertex_group_index);
+ }
+
+ WriteAttributePtr try_get_for_write(GeometryComponent &component,
+ const StringRef attribute_name) const final
+ {
+ BLI_assert(component.type() == GeometryComponentType::Mesh);
+ MeshComponent &mesh_component = static_cast<MeshComponent &>(component);
+ Mesh *mesh = mesh_component.get_for_write();
+ if (mesh == nullptr) {
+ return {};
+ }
+ const int vertex_group_index = mesh_component.vertex_group_names().lookup_default_as(
+ attribute_name, -1);
+ if (vertex_group_index < 0) {
+ return {};
+ }
+ if (mesh->dvert == nullptr) {
+ BKE_object_defgroup_data_create(&mesh->id);
+ }
+ else {
+ /* Copy the data layer if it is shared with some other mesh. */
+ mesh->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
+ &mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
+ }
+ return std::make_unique<blender::bke::VertexWeightWriteAttribute>(
+ mesh->dvert, mesh->totvert, vertex_group_index);
+ }
+
+ bool try_delete(GeometryComponent &component, const StringRef attribute_name) const final
+ {
+ BLI_assert(component.type() == GeometryComponentType::Mesh);
+ MeshComponent &mesh_component = static_cast<MeshComponent &>(component);
+
+ const int vertex_group_index = mesh_component.vertex_group_names().pop_default_as(
+ attribute_name, -1);
+ if (vertex_group_index < 0) {
+ return false;
+ }
+ Mesh *mesh = mesh_component.get_for_write();
+ if (mesh == nullptr) {
+ return true;
+ }
+ if (mesh->dvert == nullptr) {
return true;
}
+ for (MDeformVert &dvert : MutableSpan(mesh->dvert, mesh->totvert)) {
+ MDeformWeight *weight = BKE_defvert_find_index(&dvert, vertex_group_index);
+ BKE_defvert_remove_group(&dvert, weight);
+ }
+ return true;
}
- return false;
+
+ void list(const GeometryComponent &component, Set<std::string> &r_names) const final
+ {
+ BLI_assert(component.type() == GeometryComponentType::Mesh);
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ mesh_component.vertex_group_names().foreach_item(
+ [&](StringRef name, const int vertex_group_index) {
+ if (vertex_group_index >= 0) {
+ r_names.add(name);
+ }
+ });
+ }
+
+ void supported_domains(Vector<AttributeDomain> &r_domains) const final
+ {
+ r_domains.append_non_duplicates(ATTR_DOMAIN_POINT);
+ }
+};
+
+/**
+ * This is a container for multiple attribute providers that are used by one geometry component
+ * type (e.g. there is a set of attribute providers for mesh components).
+ */
+class ComponentAttributeProviders {
+ private:
+ /**
+ * Builtin attribute providers are identified by their name. Attribute names that are in this
+ * map will only be accessed using builtin attribute providers. Therefore, these providers have
+ * higher priority when an attribute name is looked up. Usually, that means that builtin
+ * providers are checked before dynamic ones.
+ */
+ Map<std::string, const BuiltinAttributeProvider *> builtin_attribute_providers_;
+ /**
+ * An ordered list of dynamic attribute providers. The order is important because that is order
+ * in which they are checked when an attribute is looked up.
+ */
+ Vector<const DynamicAttributesProvider *> dynamic_attribute_providers_;
+ /**
+ * All the domains that are supported by at least one of the providers above.
+ */
+ Vector<AttributeDomain> supported_domains_;
+
+ public:
+ ComponentAttributeProviders(Span<const BuiltinAttributeProvider *> builtin_attribute_providers,
+ Span<const DynamicAttributesProvider *> dynamic_attribute_providers)
+ : dynamic_attribute_providers_(dynamic_attribute_providers)
+ {
+ Set<AttributeDomain> domains;
+ for (const BuiltinAttributeProvider *provider : builtin_attribute_providers) {
+ /* Use #add_new to make sure that no two builtin attributes have the same name. */
+ builtin_attribute_providers_.add_new(provider->name(), provider);
+ supported_domains_.append_non_duplicates(provider->domain());
+ }
+ for (const DynamicAttributesProvider *provider : dynamic_attribute_providers) {
+ provider->supported_domains(supported_domains_);
+ }
+ }
+
+ const Map<std::string, const BuiltinAttributeProvider *> &builtin_attribute_providers() const
+ {
+ return builtin_attribute_providers_;
+ }
+
+ Span<const DynamicAttributesProvider *> dynamic_attribute_providers() const
+ {
+ return dynamic_attribute_providers_;
+ }
+
+ Span<AttributeDomain> supported_domains() const
+ {
+ return supported_domains_;
+ }
+};
+
+static float3 get_vertex_position(const MVert &vert)
+{
+ return float3(vert.co);
+}
+
+static void set_vertex_position(MVert &vert, const float3 &position)
+{
+ copy_v3_v3(vert.co, position);
+}
+
+static ReadAttributePtr make_vertex_position_read_attribute(const void *data,
+ const int domain_size)
+{
+ return std::make_unique<DerivedArrayReadAttribute<MVert, float3, get_vertex_position>>(
+ ATTR_DOMAIN_POINT, Span<MVert>((const MVert *)data, domain_size));
}
-static void get_custom_data_layer_attribute_names(const CustomData &custom_data,
- const GeometryComponent &component,
- const AttributeDomain domain,
- Set<std::string> &r_names)
+static WriteAttributePtr make_vertex_position_write_attribute(void *data, const int domain_size)
{
- for (const CustomDataLayer &layer : blender::Span(custom_data.layers, custom_data.totlayer)) {
- if (component.attribute_domain_with_type_supported(domain,
- static_cast<CustomDataType>(layer.type))) {
- r_names.add(layer.name);
+ return std::make_unique<
+ DerivedArrayWriteAttribute<MVert, float3, get_vertex_position, set_vertex_position>>(
+ ATTR_DOMAIN_POINT, MutableSpan<MVert>((MVert *)data, domain_size));
+}
+
+template<typename T, AttributeDomain Domain>
+static ReadAttributePtr make_array_read_attribute(const void *data, const int domain_size)
+{
+ return std::make_unique<ArrayReadAttribute<T>>(Domain, Span<T>((const T *)data, domain_size));
+}
+
+template<typename T, AttributeDomain Domain>
+static WriteAttributePtr make_array_write_attribute(void *data, const int domain_size)
+{
+ return std::make_unique<ArrayWriteAttribute<T>>(Domain, MutableSpan<T>((T *)data, domain_size));
+}
+
+/**
+ * In this function all the attribute providers for a mesh component are created. Most data in this
+ * function is statically allocated, because it does not change over time.
+ */
+static ComponentAttributeProviders create_attribute_providers_for_mesh()
+{
+ static auto update_custom_data_pointers = [](GeometryComponent &component) {
+ Mesh *mesh = get_mesh_from_component_for_write(component);
+ if (mesh != nullptr) {
+ BKE_mesh_update_customdata_pointers(mesh, false);
}
- }
+ };
+
+#define MAKE_MUTABLE_CUSTOM_DATA_GETTER(NAME) \
+ [](GeometryComponent &component) -> CustomData * { \
+ Mesh *mesh = get_mesh_from_component_for_write(component); \
+ return mesh ? &mesh->NAME : nullptr; \
+ }
+#define MAKE_CONST_CUSTOM_DATA_GETTER(NAME) \
+ [](const GeometryComponent &component) -> const CustomData * { \
+ const Mesh *mesh = get_mesh_from_component_for_read(component); \
+ return mesh ? &mesh->NAME : nullptr; \
+ }
+
+ static CustomDataAccessInfo corner_access = {MAKE_MUTABLE_CUSTOM_DATA_GETTER(ldata),
+ MAKE_CONST_CUSTOM_DATA_GETTER(ldata),
+ update_custom_data_pointers};
+ static CustomDataAccessInfo point_access = {MAKE_MUTABLE_CUSTOM_DATA_GETTER(vdata),
+ MAKE_CONST_CUSTOM_DATA_GETTER(vdata),
+ update_custom_data_pointers};
+ static CustomDataAccessInfo edge_access = {MAKE_MUTABLE_CUSTOM_DATA_GETTER(edata),
+ MAKE_CONST_CUSTOM_DATA_GETTER(edata),
+ update_custom_data_pointers};
+ static CustomDataAccessInfo polygon_access = {MAKE_MUTABLE_CUSTOM_DATA_GETTER(pdata),
+ MAKE_CONST_CUSTOM_DATA_GETTER(pdata),
+ update_custom_data_pointers};
+
+#undef MAKE_CONST_CUSTOM_DATA_GETTER
+#undef MAKE_MUTABLE_CUSTOM_DATA_GETTER
+
+ static BuiltinCustomDataLayerProvider position("position",
+ ATTR_DOMAIN_POINT,
+ CD_PROP_FLOAT3,
+ CD_MVERT,
+ BuiltinAttributeProvider::NonCreatable,
+ BuiltinAttributeProvider::Writable,
+ BuiltinAttributeProvider::NonDeletable,
+ point_access,
+ make_vertex_position_read_attribute,
+ make_vertex_position_write_attribute);
+ static MeshUVsAttributeProvider uvs;
+ static VertexGroupsAttributeProvider vertex_groups;
+ static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access);
+ static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access);
+ static CustomDataAttributeProvider edge_custom_data(ATTR_DOMAIN_EDGE, edge_access);
+ static CustomDataAttributeProvider polygon_custom_data(ATTR_DOMAIN_POLYGON, polygon_access);
+
+ return ComponentAttributeProviders({&position},
+ {&uvs,
+ &corner_custom_data,
+ &vertex_groups,
+ &point_custom_data,
+ &edge_custom_data,
+ &polygon_custom_data});
}
-/** \} */
+/**
+ * In this function all the attribute providers for a point cloud component are created. Most data
+ * in this function is statically allocated, because it does not change over time.
+ */
+static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
+{
+ static auto update_custom_data_pointers = [](GeometryComponent &component) {
+ PointCloudComponent &pointcloud_component = static_cast<PointCloudComponent &>(component);
+ PointCloud *pointcloud = pointcloud_component.get_for_write();
+ if (pointcloud != nullptr) {
+ BKE_pointcloud_update_customdata_pointers(pointcloud);
+ }
+ };
+ static CustomDataAccessInfo point_access = {
+ [](GeometryComponent &component) -> CustomData * {
+ PointCloudComponent &pointcloud_component = static_cast<PointCloudComponent &>(component);
+ PointCloud *pointcloud = pointcloud_component.get_for_write();
+ return pointcloud ? &pointcloud->pdata : nullptr;
+ },
+ [](const GeometryComponent &component) -> const CustomData * {
+ const PointCloudComponent &pointcloud_component = static_cast<const PointCloudComponent &>(
+ component);
+ const PointCloud *pointcloud = pointcloud_component.get_for_read();
+ return pointcloud ? &pointcloud->pdata : nullptr;
+ },
+ update_custom_data_pointers};
+
+ static BuiltinCustomDataLayerProvider position(
+ "position",
+ ATTR_DOMAIN_POINT,
+ CD_PROP_FLOAT3,
+ CD_PROP_FLOAT3,
+ BuiltinAttributeProvider::NonCreatable,
+ BuiltinAttributeProvider::Writable,
+ BuiltinAttributeProvider::NonDeletable,
+ point_access,
+ make_array_read_attribute<float3, ATTR_DOMAIN_POINT>,
+ make_array_write_attribute<float3, ATTR_DOMAIN_POINT>);
+ static BuiltinCustomDataLayerProvider radius(
+ "radius",
+ ATTR_DOMAIN_POINT,
+ CD_PROP_FLOAT,
+ CD_PROP_FLOAT,
+ BuiltinAttributeProvider::Creatable,
+ BuiltinAttributeProvider::Writable,
+ BuiltinAttributeProvider::Deletable,
+ point_access,
+ make_array_read_attribute<float, ATTR_DOMAIN_POINT>,
+ make_array_write_attribute<float, ATTR_DOMAIN_POINT>);
+ static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access);
+ return ComponentAttributeProviders({&position, &radius}, {&point_custom_data});
+}
+
+} // namespace blender::bke
/* -------------------------------------------------------------------- */
/** \name Geometry Component
* \{ */
-bool GeometryComponent::attribute_domain_supported(const AttributeDomain UNUSED(domain)) const
+const blender::bke::ComponentAttributeProviders *GeometryComponent::get_attribute_providers() const
{
- return false;
+ return nullptr;
}
-bool GeometryComponent::attribute_domain_with_type_supported(
- const AttributeDomain UNUSED(domain), const CustomDataType UNUSED(data_type)) const
+bool GeometryComponent::attribute_domain_supported(const AttributeDomain domain) const
{
- return false;
+ using namespace blender::bke;
+ const ComponentAttributeProviders *providers = this->get_attribute_providers();
+ if (providers == nullptr) {
+ return false;
+ }
+ return providers->supported_domains().contains(domain);
}
int GeometryComponent::attribute_domain_size(const AttributeDomain UNUSED(domain)) const
@@ -627,47 +1345,127 @@ int GeometryComponent::attribute_domain_size(const AttributeDomain UNUSED(domain
return 0;
}
-bool GeometryComponent::attribute_is_builtin(const StringRef UNUSED(attribute_name)) const
-{
- return true;
-}
-
ReadAttributePtr GeometryComponent::attribute_try_get_for_read(
- const StringRef UNUSED(attribute_name)) const
+ const StringRef attribute_name) const
{
+ using namespace blender::bke;
+ const ComponentAttributeProviders *providers = this->get_attribute_providers();
+ if (providers == nullptr) {
+ return {};
+ }
+ const BuiltinAttributeProvider *builtin_provider =
+ providers->builtin_attribute_providers().lookup_default_as(attribute_name, nullptr);
+ if (builtin_provider != nullptr) {
+ return builtin_provider->try_get_for_read(*this);
+ }
+ for (const DynamicAttributesProvider *dynamic_provider :
+ providers->dynamic_attribute_providers()) {
+ ReadAttributePtr attribute = dynamic_provider->try_get_for_read(*this, attribute_name);
+ if (attribute) {
+ return attribute;
+ }
+ }
return {};
}
-ReadAttributePtr GeometryComponent::attribute_try_adapt_domain(ReadAttributePtr attribute,
- const AttributeDomain domain) const
+ReadAttributePtr GeometryComponent::attribute_try_adapt_domain(
+ ReadAttributePtr attribute, const AttributeDomain new_domain) const
{
- if (attribute && attribute->domain() == domain) {
+ if (attribute && attribute->domain() == new_domain) {
return attribute;
}
return {};
}
-WriteAttributePtr GeometryComponent::attribute_try_get_for_write(
- const StringRef UNUSED(attribute_name))
+WriteAttributePtr GeometryComponent::attribute_try_get_for_write(const StringRef attribute_name)
{
+ using namespace blender::bke;
+ const ComponentAttributeProviders *providers = this->get_attribute_providers();
+ if (providers == nullptr) {
+ return {};
+ }
+ const BuiltinAttributeProvider *builtin_provider =
+ providers->builtin_attribute_providers().lookup_default_as(attribute_name, nullptr);
+ if (builtin_provider != nullptr) {
+ return builtin_provider->try_get_for_write(*this);
+ }
+ for (const DynamicAttributesProvider *dynamic_provider :
+ providers->dynamic_attribute_providers()) {
+ WriteAttributePtr attribute = dynamic_provider->try_get_for_write(*this, attribute_name);
+ if (attribute) {
+ return attribute;
+ }
+ }
return {};
}
-bool GeometryComponent::attribute_try_delete(const StringRef UNUSED(attribute_name))
+bool GeometryComponent::attribute_try_delete(const StringRef attribute_name)
{
- return false;
+ using namespace blender::bke;
+ const ComponentAttributeProviders *providers = this->get_attribute_providers();
+ if (providers == nullptr) {
+ return {};
+ }
+ const BuiltinAttributeProvider *builtin_provider =
+ providers->builtin_attribute_providers().lookup_default_as(attribute_name, nullptr);
+ if (builtin_provider != nullptr) {
+ return builtin_provider->try_delete(*this);
+ }
+ bool success = false;
+ for (const DynamicAttributesProvider *dynamic_provider :
+ providers->dynamic_attribute_providers()) {
+ success = dynamic_provider->try_delete(*this, attribute_name) || success;
+ }
+ return success;
}
-bool GeometryComponent::attribute_try_create(const StringRef UNUSED(attribute_name),
- const AttributeDomain UNUSED(domain),
- const CustomDataType UNUSED(data_type))
+bool GeometryComponent::attribute_try_create(const StringRef attribute_name,
+ const AttributeDomain domain,
+ const CustomDataType data_type)
{
+ using namespace blender::bke;
+ const ComponentAttributeProviders *providers = this->get_attribute_providers();
+ if (providers == nullptr) {
+ return {};
+ }
+ const BuiltinAttributeProvider *builtin_provider =
+ providers->builtin_attribute_providers().lookup_default_as(attribute_name, nullptr);
+ if (builtin_provider != nullptr) {
+ if (builtin_provider->domain() != domain) {
+ return false;
+ }
+ if (builtin_provider->data_type() != data_type) {
+ return false;
+ }
+ return builtin_provider->try_create(*this);
+ }
+ for (const DynamicAttributesProvider *dynamic_provider :
+ providers->dynamic_attribute_providers()) {
+ if (dynamic_provider->try_create(*this, attribute_name, domain, data_type)) {
+ return true;
+ }
+ }
return false;
}
Set<std::string> GeometryComponent::attribute_names() const
{
- return {};
+ using namespace blender::bke;
+ const ComponentAttributeProviders *providers = this->get_attribute_providers();
+ if (providers == nullptr) {
+ return {};
+ }
+ Set<std::string> names;
+ for (const BuiltinAttributeProvider *provider :
+ providers->builtin_attribute_providers().values()) {
+ if (provider->exists(*this)) {
+ names.add_new(provider->name());
+ }
+ }
+ for (const DynamicAttributesProvider *provider : providers->dynamic_attribute_providers()) {
+ provider->list(*this, names);
+ }
+ return names;
}
bool GeometryComponent::attribute_exists(const blender::StringRef attribute_name) const
@@ -701,10 +1499,6 @@ ReadAttributePtr GeometryComponent::attribute_try_get_for_read(
const AttributeDomain domain,
const CustomDataType data_type) const
{
- if (!this->attribute_domain_with_type_supported(domain, data_type)) {
- return {};
- }
-
ReadAttributePtr attribute = this->attribute_try_get_for_read(attribute_name);
if (!attribute) {
return {};
@@ -756,8 +1550,6 @@ ReadAttributePtr GeometryComponent::attribute_get_for_read(const StringRef attri
const CustomDataType data_type,
const void *default_value) const
{
- BLI_assert(this->attribute_domain_with_type_supported(domain, data_type));
-
ReadAttributePtr attribute = this->attribute_try_get_for_read(attribute_name, domain, data_type);
if (attribute) {
return attribute;
@@ -817,8 +1609,6 @@ OutputAttributePtr GeometryComponent::attribute_try_get_for_output(const StringR
const CustomDataType data_type,
const void *default_value)
{
- BLI_assert(this->attribute_domain_with_type_supported(domain, data_type));
-
const blender::fn::CPPType *cpp_type = blender::bke::custom_data_type_to_cpp_type(data_type);
BLI_assert(cpp_type != nullptr);
@@ -946,21 +1736,12 @@ void OutputAttributePtr::apply_span_and_save()
/** \name Point Cloud Component
* \{ */
-bool PointCloudComponent::attribute_domain_supported(const AttributeDomain domain) const
+const blender::bke::ComponentAttributeProviders *PointCloudComponent::get_attribute_providers()
+ const
{
- return domain == ATTR_DOMAIN_POINT;
-}
-
-bool PointCloudComponent::attribute_domain_with_type_supported(
- const AttributeDomain domain, const CustomDataType data_type) const
-{
- return domain == ATTR_DOMAIN_POINT && ELEM(data_type,
- CD_PROP_BOOL,
- CD_PROP_FLOAT,
- CD_PROP_FLOAT2,
- CD_PROP_FLOAT3,
- CD_PROP_INT32,
- CD_PROP_COLOR);
+ static blender::bke::ComponentAttributeProviders providers =
+ blender::bke::create_attribute_providers_for_point_cloud();
+ return &providers;
}
int PointCloudComponent::attribute_domain_size(const AttributeDomain domain) const
@@ -973,119 +1754,17 @@ int PointCloudComponent::attribute_domain_size(const AttributeDomain domain) con
return pointcloud_->totpoint;
}
-bool PointCloudComponent::attribute_is_builtin(const StringRef attribute_name) const
-{
- return attribute_name == "position";
-}
-
-ReadAttributePtr PointCloudComponent::attribute_try_get_for_read(
- const StringRef attribute_name) const
-{
- if (pointcloud_ == nullptr) {
- return {};
- }
-
- return read_attribute_from_custom_data(
- pointcloud_->pdata, pointcloud_->totpoint, attribute_name, ATTR_DOMAIN_POINT);
-}
-
-WriteAttributePtr PointCloudComponent::attribute_try_get_for_write(const StringRef attribute_name)
-{
- PointCloud *pointcloud = this->get_for_write();
- if (pointcloud == nullptr) {
- return {};
- }
-
- return write_attribute_from_custom_data(
- pointcloud->pdata, pointcloud->totpoint, attribute_name, ATTR_DOMAIN_POINT, [&]() {
- BKE_pointcloud_update_customdata_pointers(pointcloud);
- });
-}
-
-bool PointCloudComponent::attribute_try_delete(const StringRef attribute_name)
-{
- if (this->attribute_is_builtin(attribute_name)) {
- return false;
- }
- PointCloud *pointcloud = this->get_for_write();
- if (pointcloud == nullptr) {
- return false;
- }
- delete_named_custom_data_layer(pointcloud->pdata, attribute_name, pointcloud->totpoint);
- return true;
-}
-
-static bool custom_data_has_layer_with_name(const CustomData &custom_data, const StringRef name)
-{
- for (const CustomDataLayer &layer : blender::Span(custom_data.layers, custom_data.totlayer)) {
- if (layer.name == name) {
- return true;
- }
- }
- return false;
-}
-
-bool PointCloudComponent::attribute_try_create(const StringRef attribute_name,
- const AttributeDomain domain,
- const CustomDataType data_type)
-{
- if (this->attribute_is_builtin(attribute_name)) {
- return false;
- }
- if (!this->attribute_domain_with_type_supported(domain, data_type)) {
- return false;
- }
- PointCloud *pointcloud = this->get_for_write();
- if (pointcloud == nullptr) {
- return false;
- }
- if (custom_data_has_layer_with_name(pointcloud->pdata, attribute_name)) {
- return false;
- }
-
- char attribute_name_c[MAX_NAME];
- attribute_name.copy(attribute_name_c);
- CustomData_add_layer_named(
- &pointcloud->pdata, data_type, CD_DEFAULT, nullptr, pointcloud_->totpoint, attribute_name_c);
- return true;
-}
-
-Set<std::string> PointCloudComponent::attribute_names() const
-{
- if (pointcloud_ == nullptr) {
- return {};
- }
-
- Set<std::string> names;
- get_custom_data_layer_attribute_names(pointcloud_->pdata, *this, ATTR_DOMAIN_POINT, names);
- return names;
-}
-
/** \} */
/* -------------------------------------------------------------------- */
/** \name Mesh Component
* \{ */
-bool MeshComponent::attribute_domain_supported(const AttributeDomain domain) const
+const blender::bke::ComponentAttributeProviders *MeshComponent::get_attribute_providers() const
{
- return ELEM(
- domain, ATTR_DOMAIN_CORNER, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_POLYGON);
-}
-
-bool MeshComponent::attribute_domain_with_type_supported(const AttributeDomain domain,
- const CustomDataType data_type) const
-{
- if (!this->attribute_domain_supported(domain)) {
- return false;
- }
- return ELEM(data_type,
- CD_PROP_BOOL,
- CD_PROP_FLOAT,
- CD_PROP_FLOAT2,
- CD_PROP_FLOAT3,
- CD_PROP_INT32,
- CD_PROP_COLOR);
+ static blender::bke::ComponentAttributeProviders providers =
+ blender::bke::create_attribute_providers_for_mesh();
+ return &providers;
}
int MeshComponent::attribute_domain_size(const AttributeDomain domain) const
@@ -1110,228 +1789,75 @@ int MeshComponent::attribute_domain_size(const AttributeDomain domain) const
return 0;
}
-bool MeshComponent::attribute_is_builtin(const StringRef attribute_name) const
-{
- return attribute_name == "position";
-}
+namespace blender::bke {
-ReadAttributePtr MeshComponent::attribute_try_get_for_read(const StringRef attribute_name) const
+template<typename T>
+void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
+ const TypedReadAttribute<T> &attribute,
+ MutableSpan<T> r_values)
{
- if (mesh_ == nullptr) {
- return {};
- }
-
- if (attribute_name == "position") {
- auto get_vertex_position = [](const MVert &vert) { return float3(vert.co); };
- return std::make_unique<
- blender::bke::DerivedArrayReadAttribute<MVert, float3, decltype(get_vertex_position)>>(
- ATTR_DOMAIN_POINT, blender::Span(mesh_->mvert, mesh_->totvert), get_vertex_position);
- }
-
- ReadAttributePtr corner_attribute = read_attribute_from_custom_data(
- mesh_->ldata, mesh_->totloop, attribute_name, ATTR_DOMAIN_CORNER);
- if (corner_attribute) {
- return corner_attribute;
- }
-
- const int vertex_group_index = vertex_group_names_.lookup_default(attribute_name, -1);
- if (vertex_group_index >= 0) {
- return std::make_unique<blender::bke::VertexWeightReadAttribute>(
- mesh_->dvert, mesh_->totvert, vertex_group_index);
- }
+ BLI_assert(r_values.size() == mesh.totvert);
+ attribute_math::DefaultMixer<T> mixer(r_values);
- ReadAttributePtr vertex_attribute = read_attribute_from_custom_data(
- mesh_->vdata, mesh_->totvert, attribute_name, ATTR_DOMAIN_POINT);
- if (vertex_attribute) {
- return vertex_attribute;
+ for (const int loop_index : IndexRange(mesh.totloop)) {
+ const T value = attribute[loop_index];
+ const MLoop &loop = mesh.mloop[loop_index];
+ const int point_index = loop.v;
+ mixer.mix_in(point_index, value);
}
-
- ReadAttributePtr edge_attribute = read_attribute_from_custom_data(
- mesh_->edata, mesh_->totedge, attribute_name, ATTR_DOMAIN_EDGE);
- if (edge_attribute) {
- return edge_attribute;
- }
-
- ReadAttributePtr polygon_attribute = read_attribute_from_custom_data(
- mesh_->pdata, mesh_->totpoly, attribute_name, ATTR_DOMAIN_POLYGON);
- if (polygon_attribute) {
- return polygon_attribute;
- }
-
- return {};
+ mixer.finalize();
}
-WriteAttributePtr MeshComponent::attribute_try_get_for_write(const StringRef attribute_name)
+static ReadAttributePtr adapt_mesh_domain_corner_to_point(const Mesh &mesh,
+ ReadAttributePtr attribute)
{
- Mesh *mesh = this->get_for_write();
- if (mesh == nullptr) {
- return {};
- }
-
- const std::function<void()> update_mesh_pointers = [&]() {
- BKE_mesh_update_customdata_pointers(mesh, false);
- };
-
- if (attribute_name == "position") {
- CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
- update_mesh_pointers();
-
- auto get_vertex_position = [](const MVert &vert) { return float3(vert.co); };
- auto set_vertex_position = [](MVert &vert, const float3 &co) { copy_v3_v3(vert.co, co); };
- return std::make_unique<
- blender::bke::DerivedArrayWriteAttribute<MVert,
- float3,
- decltype(get_vertex_position),
- decltype(set_vertex_position)>>(
- ATTR_DOMAIN_POINT,
- blender::MutableSpan(mesh_->mvert, mesh_->totvert),
- get_vertex_position,
- set_vertex_position);
- }
-
- WriteAttributePtr corner_attribute = write_attribute_from_custom_data(
- mesh_->ldata, mesh_->totloop, attribute_name, ATTR_DOMAIN_CORNER, update_mesh_pointers);
- if (corner_attribute) {
- return corner_attribute;
- }
-
- const int vertex_group_index = vertex_group_names_.lookup_default_as(attribute_name, -1);
- if (vertex_group_index >= 0) {
- if (mesh_->dvert == nullptr) {
- BKE_object_defgroup_data_create(&mesh_->id);
+ ReadAttributePtr new_attribute;
+ const CustomDataType data_type = attribute->custom_data_type();
+ attribute_math::convert_to_static_type(data_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, *attribute, values);
+ new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
+ std::move(values));
}
- else {
- /* Copy the data layer if it is shared with some other mesh. */
- mesh_->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
- &mesh_->vdata, CD_MDEFORMVERT, mesh_->totvert);
- }
- return std::make_unique<blender::bke::VertexWeightWriteAttribute>(
- mesh_->dvert, mesh_->totvert, vertex_group_index);
- }
-
- WriteAttributePtr vertex_attribute = write_attribute_from_custom_data(
- mesh_->vdata, mesh_->totvert, attribute_name, ATTR_DOMAIN_POINT, update_mesh_pointers);
- if (vertex_attribute) {
- return vertex_attribute;
- }
-
- WriteAttributePtr edge_attribute = write_attribute_from_custom_data(
- mesh_->edata, mesh_->totedge, attribute_name, ATTR_DOMAIN_EDGE, update_mesh_pointers);
- if (edge_attribute) {
- return edge_attribute;
- }
-
- WriteAttributePtr polygon_attribute = write_attribute_from_custom_data(
- mesh_->pdata, mesh_->totpoly, attribute_name, ATTR_DOMAIN_POLYGON, update_mesh_pointers);
- if (polygon_attribute) {
- return polygon_attribute;
- }
-
- return {};
+ });
+ return new_attribute;
}
-bool MeshComponent::attribute_try_delete(const StringRef attribute_name)
-{
- if (this->attribute_is_builtin(attribute_name)) {
- return false;
- }
- Mesh *mesh = this->get_for_write();
- if (mesh == nullptr) {
- return false;
- }
-
- delete_named_custom_data_layer(mesh_->ldata, attribute_name, mesh_->totloop);
- delete_named_custom_data_layer(mesh_->vdata, attribute_name, mesh_->totvert);
- delete_named_custom_data_layer(mesh_->edata, attribute_name, mesh_->totedge);
- delete_named_custom_data_layer(mesh_->pdata, attribute_name, mesh_->totpoly);
-
- const int vertex_group_index = vertex_group_names_.lookup_default_as(attribute_name, -1);
- if (vertex_group_index != -1) {
- for (MDeformVert &dvert : blender::MutableSpan(mesh_->dvert, mesh_->totvert)) {
- MDeformWeight *weight = BKE_defvert_find_index(&dvert, vertex_group_index);
- BKE_defvert_remove_group(&dvert, weight);
- }
- vertex_group_names_.remove_as(attribute_name);
- }
-
- return true;
-}
+} // namespace blender::bke
-bool MeshComponent::attribute_try_create(const StringRef attribute_name,
- const AttributeDomain domain,
- const CustomDataType data_type)
+ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attribute,
+ const AttributeDomain new_domain) const
{
- if (this->attribute_is_builtin(attribute_name)) {
- return false;
+ if (!attribute) {
+ return {};
}
- if (!this->attribute_domain_with_type_supported(domain, data_type)) {
- return false;
+ if (attribute->size() == 0) {
+ return {};
}
- Mesh *mesh = this->get_for_write();
- if (mesh == nullptr) {
- return false;
+ const AttributeDomain old_domain = attribute->domain();
+ if (old_domain == new_domain) {
+ return attribute;
}
- char attribute_name_c[MAX_NAME];
- attribute_name.copy(attribute_name_c);
-
- switch (domain) {
+ switch (old_domain) {
case ATTR_DOMAIN_CORNER: {
- if (custom_data_has_layer_with_name(mesh->ldata, attribute_name)) {
- return false;
- }
- CustomData_add_layer_named(
- &mesh->ldata, data_type, CD_DEFAULT, nullptr, mesh->totloop, attribute_name_c);
- return true;
- }
- case ATTR_DOMAIN_POINT: {
- if (custom_data_has_layer_with_name(mesh->vdata, attribute_name)) {
- return false;
- }
- if (vertex_group_names_.contains_as(attribute_name)) {
- return false;
- }
- CustomData_add_layer_named(
- &mesh->vdata, data_type, CD_DEFAULT, nullptr, mesh->totvert, attribute_name_c);
- return true;
- }
- case ATTR_DOMAIN_EDGE: {
- if (custom_data_has_layer_with_name(mesh->edata, attribute_name)) {
- return false;
- }
- CustomData_add_layer_named(
- &mesh->edata, data_type, CD_DEFAULT, nullptr, mesh->totedge, attribute_name_c);
- return true;
- }
- case ATTR_DOMAIN_POLYGON: {
- if (custom_data_has_layer_with_name(mesh->pdata, attribute_name)) {
- return false;
+ switch (new_domain) {
+ case ATTR_DOMAIN_POINT:
+ return blender::bke::adapt_mesh_domain_corner_to_point(*mesh_, std::move(attribute));
+ default:
+ break;
}
- CustomData_add_layer_named(
- &mesh->pdata, data_type, CD_DEFAULT, nullptr, mesh->totpoly, attribute_name_c);
- return true;
+ break;
}
default:
- return false;
- }
-}
-
-Set<std::string> MeshComponent::attribute_names() const
-{
- if (mesh_ == nullptr) {
- return {};
+ break;
}
- Set<std::string> names;
- names.add("position");
- for (StringRef name : vertex_group_names_.keys()) {
- names.add(name);
- }
- get_custom_data_layer_attribute_names(mesh_->pdata, *this, ATTR_DOMAIN_CORNER, names);
- get_custom_data_layer_attribute_names(mesh_->vdata, *this, ATTR_DOMAIN_POINT, names);
- get_custom_data_layer_attribute_names(mesh_->edata, *this, ATTR_DOMAIN_EDGE, names);
- get_custom_data_layer_attribute_names(mesh_->pdata, *this, ATTR_DOMAIN_POLYGON, names);
- return names;
+ return {};
}
/** \} */
diff --git a/source/blender/blenkernel/intern/attribute_math.cc b/source/blender/blenkernel/intern/attribute_math.cc
new file mode 100644
index 00000000000..4ff3a6ceff5
--- /dev/null
+++ b/source/blender/blenkernel/intern/attribute_math.cc
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BKE_attribute_math.hh"
+
+namespace blender::attribute_math {
+
+Color4fMixer::Color4fMixer(MutableSpan<Color4f> output_buffer, Color4f default_color)
+ : buffer_(output_buffer),
+ default_color_(default_color),
+ total_weights_(output_buffer.size(), 0.0f)
+{
+ buffer_.fill(Color4f(0, 0, 0, 0));
+}
+
+void Color4fMixer::mix_in(const int64_t index, const Color4f &color, const float weight)
+{
+ BLI_assert(weight >= 0.0f);
+ Color4f &output_color = buffer_[index];
+ output_color.r += color.r * weight;
+ output_color.g += color.g * weight;
+ output_color.b += color.b * weight;
+ output_color.a += color.a * weight;
+ total_weights_[index] += weight;
+}
+
+void Color4fMixer::finalize()
+{
+ for (const int64_t i : buffer_.index_range()) {
+ const float weight = total_weights_[i];
+ Color4f &output_color = buffer_[i];
+ if (weight > 0.0f) {
+ const float weight_inv = 1.0f / weight;
+ output_color.r *= weight_inv;
+ output_color.g *= weight_inv;
+ output_color.b *= weight_inv;
+ output_color.a *= weight_inv;
+ }
+ else {
+ output_color = default_color_;
+ }
+ }
+}
+
+} // namespace blender::attribute_math
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index 9e061b1ac69..d826aaf24e3 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -48,6 +48,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_undo_system.h"
#include "BLO_readfile.h"
#include "BLO_undofile.h"
@@ -62,7 +63,7 @@
#define UNDO_DISK 0
bool BKE_memfile_undo_decode(MemFileUndoData *mfu,
- const int undo_direction,
+ const eUndoStepDir undo_direction,
const bool use_old_bmain_data,
bContext *C)
{
@@ -80,7 +81,7 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu,
}
else {
struct BlendFileReadParams params = {0};
- params.undo_direction = undo_direction > 0 ? 1 : -1;
+ params.undo_direction = undo_direction;
if (!use_old_bmain_data) {
params.skip_flags |= BLO_READ_SKIP_UNDO_OLD_MAIN;
}
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index 0855db1a943..32710c4fa60 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -57,6 +57,7 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_studiolight.h"
+#include "BKE_undo_system.h"
#include "BKE_workspace.h"
#include "BLO_readfile.h"
@@ -148,7 +149,7 @@ static void setup_app_data(bContext *C,
LOAD_UNDO,
} mode;
- if (params->undo_direction != 0) {
+ if (params->undo_direction != STEP_INVALID) {
BLI_assert(bfd->curscene != NULL);
mode = LOAD_UNDO;
}
@@ -647,6 +648,10 @@ UserDef *BKE_blendfile_userdef_from_defaults(void)
BKE_studiolight_default(userdef->light_param, userdef->light_ambient);
BKE_preferences_asset_library_default_add(userdef);
+ /* Enable asset browser features by default for alpha testing.
+ * BLO_sanitize_experimental_features_userpref_blend() will disable it again for non-alpha
+ * builds. */
+ userdef->experimental.use_asset_browser = true;
return userdef;
}
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 762ced7dc5f..2ad0ac950d0 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -23,7 +23,7 @@
* - passing output paths to the visitor?, like render out.
* - passing sequence strips with many images.
* - passing directory paths - visitors don't know which path is a dir or a file.
- * */
+ */
#include <sys/stat.h>
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 9a954a89cad..59ff59b82e0 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -375,7 +375,7 @@ static int brush_undo_preserve_cb(LibraryIDLinkCallbackData *cb_data)
static void brush_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
{
- /* Whole Brush is preserved accross undo's. */
+ /* Whole Brush is preserved across undo-steps. */
BKE_lib_id_swap(NULL, id_new, id_old);
/* `id_new` now has content from `id_old`, we need to ensure those old ID pointers are valid.
@@ -410,6 +410,8 @@ IDTypeInfo IDType_ID_BR = {
.blend_read_expand = brush_blend_read_expand,
.blend_read_undo_preserve = brush_undo_preserve,
+
+ .lib_override_apply_post = NULL,
};
static RNG *brush_rng;
@@ -973,12 +975,12 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
break;
}
case GP_BRUSH_PRESET_FILL_AREA: {
- brush->size = 20.0f;
+ 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;
+ brush->gpencil_settings->fill_factor = 1.0f;
brush->gpencil_settings->draw_strength = 1.0f;
brush->gpencil_settings->hardeness = 1.0f;
@@ -987,6 +989,8 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->draw_smoothlvl = 1;
brush->gpencil_settings->draw_subdivide = 1;
+ brush->gpencil_settings->flag |= GP_BRUSH_FILL_SHOW_EXTENDLINES;
+
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_FILL;
brush->gpencil_tool = GPAINT_TOOL_FILL;
brush->gpencil_settings->vertex_mode = GPPAINT_MODE_FILL;
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index fd5cb33f02d..790fb128c7c 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -27,6 +27,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_pointcloud_types.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
@@ -1717,3 +1718,41 @@ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
memset(data, 0, sizeof(*data));
}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Point Cloud BVH Building
+ * \{ */
+
+BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data,
+ const PointCloud *pointcloud,
+ const int tree_type)
+{
+ BVHTree *tree = BLI_bvhtree_new(pointcloud->totpoint, 0.0f, tree_type, 6);
+ if (!tree) {
+ return NULL;
+ }
+
+ for (int i = 0; i < pointcloud->totpoint; i++) {
+ BLI_bvhtree_insert(tree, i, pointcloud->co[i], 1);
+ }
+ BLI_assert(BLI_bvhtree_get_len(tree) == pointcloud->totpoint);
+ BLI_bvhtree_balance(tree);
+
+ data->coords = pointcloud->co;
+ data->tree = tree;
+ data->nearest_callback = NULL;
+
+ return tree;
+}
+
+void free_bvhtree_from_pointcloud(BVHTreeFromPointCloud *data)
+{
+ if (data->tree) {
+ BLI_bvhtree_free(data->tree);
+ }
+ memset(data, 0, sizeof(*data));
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index d6c31809a2e..1e2139522f1 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -142,6 +142,8 @@ IDTypeInfo IDType_ID_CF = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* TODO: make this per cache file to avoid global locks. */
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 0ca22e34973..b0e3743add1 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -203,6 +203,8 @@ IDTypeInfo IDType_ID_CA = {
.blend_read_expand = camera_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/** \} */
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index c2d6d5c7594..09bd397cc78 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -285,7 +285,7 @@ static int do_step_cloth(
mul_m4_v3(ob->obmat, verts->xconst);
}
- effectors = BKE_effectors_create(depsgraph, ob, NULL, clmd->sim_parms->effector_weights);
+ effectors = BKE_effectors_create(depsgraph, ob, NULL, clmd->sim_parms->effector_weights, false);
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) {
cloth_update_verts(ob, clmd, result);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 58ce7227398..dd0572f9b12 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -362,6 +362,8 @@ IDTypeInfo IDType_ID_GR = {
.blend_read_expand = collection_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/** \} */
@@ -1907,7 +1909,7 @@ bool BKE_collection_move(Main *bmain,
/** \name Iterators
* \{ */
-/* scene collection iteractor */
+/* Scene collection iterator. */
typedef struct CollectionsIteratorData {
Scene *scene;
@@ -1939,27 +1941,28 @@ static void scene_collections_build_array(Collection *collection, void *data)
(*array)++;
}
-static void scene_collections_array(Scene *scene, Collection ***collections_array, int *tot)
+static void scene_collections_array(Scene *scene,
+ Collection ***r_collections_array,
+ int *r_collections_array_len)
{
- Collection *collection;
- Collection **array;
-
- *collections_array = NULL;
- *tot = 0;
+ *r_collections_array = NULL;
+ *r_collections_array_len = 0;
if (scene == NULL) {
return;
}
- collection = scene->master_collection;
+ Collection *collection = scene->master_collection;
BLI_assert(collection != NULL);
- scene_collection_callback(collection, scene_collections_count, tot);
+ scene_collection_callback(collection, scene_collections_count, r_collections_array_len);
- if (*tot == 0) {
+ if (*r_collections_array_len == 0) {
return;
}
- *collections_array = array = MEM_mallocN(sizeof(Collection *) * (*tot), "CollectionArray");
+ Collection **array = MEM_mallocN(sizeof(Collection *) * (*r_collections_array_len),
+ "CollectionArray");
+ *r_collections_array = array;
scene_collection_callback(collection, scene_collections_build_array, &array);
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 0bf27a50a32..d04a27adec8 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -4693,7 +4693,7 @@ static void pivotcon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *ta
copy_m3_m4(rotMat, cob->matrix);
normalize_m3(rotMat);
- /* correct the pivot by the rotation axis otherwise the pivot translates when it shouldnt */
+ /* correct the pivot by the rotation axis otherwise the pivot translates when it shouldn't */
mat3_normalized_to_axis_angle(axis, &angle, rotMat);
if (angle) {
float dvec[3];
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 65accc66084..6bc385ecd31 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -318,7 +318,7 @@ static eContextResult ctx_data_get(bContext *C, const char *member, bContextData
*
* Values in order of importance
* (0, -1, 1) - Where 1 is highest priority
- * */
+ */
if (done != 1 && recursion < 1 && C->wm.store) {
C->data.recursion = 1;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index ebce28c4e23..5632ae28960 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -327,6 +327,8 @@ IDTypeInfo IDType_ID_CU = {
.blend_read_expand = curve_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
static int cu_isectLL(const float v1[3],
@@ -2373,7 +2375,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
* 0,1,2,3,4 --> 1,2,3,4,0
*
* this is why we compare last with second last
- * */
+ */
float vec_1[3] = {0, 1, 0}, vec_2[3] = {0, 1, 0}, angle, ang_fac, cross_tmp[3];
BevPoint *bevp_first;
diff --git a/source/blender/blenkernel/intern/curve_deform.c b/source/blender/blenkernel/intern/curve_deform.c
index 4725be6d302..63da7c1dd11 100644
--- a/source/blender/blenkernel/intern/curve_deform.c
+++ b/source/blender/blenkernel/intern/curve_deform.c
@@ -233,7 +233,7 @@ static bool calc_curve_deform(
* Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell
*
* note: moved functions into quat_apply_track/vec_apply_track
- * */
+ */
copy_qt_qt(quat, new_quat);
copy_v3_v3(cent, co);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 1121df0d568..782b4fc200e 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -212,9 +212,9 @@ static void layerFree_mdeformvert(void *data, int count, int size)
/* copy just zeros in this case */
static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest, int count)
{
- int i, size = sizeof(void *);
+ const int size = sizeof(void *);
- for (i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++) {
void **ptr = POINTER_OFFSET(dest, i * size);
*ptr = NULL;
}
@@ -253,15 +253,14 @@ static void layerInterp_mdeformvert(const void **sources,
MDeformVert *dvert = dest;
struct MDeformWeight_Link *dest_dwlink = NULL;
struct MDeformWeight_Link *node;
- int i, j, totweight;
/* build a list of unique def_nrs for dest */
- totweight = 0;
- for (i = 0; i < count; i++) {
+ int totweight = 0;
+ for (int i = 0; i < count; i++) {
const MDeformVert *source = sources[i];
float interp_weight = weights[i];
- for (j = 0; j < source->totweight; j++) {
+ for (int j = 0; j < source->totweight; j++) {
MDeformWeight *dw = &source->dw[j];
float weight = dw->weight * interp_weight;
@@ -311,7 +310,8 @@ static void layerInterp_mdeformvert(const void **sources,
if (totweight) {
dvert->totweight = totweight;
- for (i = 0, node = dest_dwlink; node; node = node->next, i++) {
+ int i = 0;
+ for (node = dest_dwlink; node; node = node->next, i++) {
if (node->dw.weight > 1.0f) {
node->dw.weight = 1.0f;
}
@@ -416,18 +416,16 @@ static void layerInterp_tface(
const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
{
MTFace *tf = dest;
- int i, j, k;
float uv[4][2] = {{0.0f}};
- const float *sub_weight;
- sub_weight = sub_weights;
- for (i = 0; i < count; i++) {
+ const float *sub_weight = sub_weights;
+ for (int i = 0; i < count; i++) {
const float interp_weight = weights[i];
const MTFace *src = sources[i];
- for (j = 0; j < 4; j++) {
+ for (int j = 0; j < 4; j++) {
if (sub_weights) {
- for (k = 0; k < 4; k++, sub_weight++) {
+ for (int k = 0; k < 4; k++, sub_weight++) {
madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight);
}
}
@@ -446,9 +444,8 @@ static void layerSwap_tface(void *data, const int *corner_indices)
{
MTFace *tf = data;
float uv[4][2];
- int j;
- for (j = 0; j < 4; j++) {
+ for (int j = 0; j < 4; j++) {
const int source_index = corner_indices[j];
copy_v2_v2(uv[j], tf->uv[source_index]);
}
@@ -517,18 +514,16 @@ static void layerInterp_origspace_face(
const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
{
OrigSpaceFace *osf = dest;
- int i, j, k;
float uv[4][2] = {{0.0f}};
- const float *sub_weight;
- sub_weight = sub_weights;
- for (i = 0; i < count; i++) {
+ const float *sub_weight = sub_weights;
+ for (int i = 0; i < count; i++) {
const float interp_weight = weights[i];
const OrigSpaceFace *src = sources[i];
- for (j = 0; j < 4; j++) {
+ for (int j = 0; j < 4; j++) {
if (sub_weights) {
- for (k = 0; k < 4; k++, sub_weight++) {
+ for (int k = 0; k < 4; k++, sub_weight++) {
madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight);
}
}
@@ -546,9 +541,8 @@ static void layerSwap_origspace_face(void *data, const int *corner_indices)
{
OrigSpaceFace *osf = data;
float uv[4][2];
- int j;
- for (j = 0; j < 4; j++) {
+ for (int j = 0; j < 4; j++) {
copy_v2_v2(uv[j], osf->uv[corner_indices[j]]);
}
memcpy(osf->uv, uv, sizeof(osf->uv));
@@ -567,13 +561,11 @@ static void layerDefault_origspace_face(void *data, int count)
static void layerSwap_mdisps(void *data, const int *ci)
{
MDisps *s = data;
- float(*d)[3] = NULL;
- int corners, cornersize, S;
if (s->disps) {
int nverts = (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */
- corners = multires_mdisp_corners(s);
- cornersize = s->totdisp / corners;
+ int corners = multires_mdisp_corners(s);
+ int cornersize = s->totdisp / corners;
if (corners != nverts) {
/* happens when face changed vertex count in edit mode
@@ -585,9 +577,9 @@ static void layerSwap_mdisps(void *data, const int *ci)
return;
}
- d = MEM_calloc_arrayN(s->totdisp, sizeof(float[3]), "mdisps swap");
+ float(*d)[3] = MEM_calloc_arrayN(s->totdisp, sizeof(float[3]), "mdisps swap");
- for (S = 0; S < corners; S++) {
+ for (int S = 0; S < corners; S++) {
memcpy(d + cornersize * S, s->disps + cornersize * ci[S], sizeof(float[3]) * cornersize);
}
@@ -1128,9 +1120,8 @@ static void layerSwap_mcol(void *data, const int *corner_indices)
{
MCol *mcol = data;
MCol col[4];
- int j;
- for (j = 0; j < 4; j++) {
+ for (int j = 0; j < 4; j++) {
col[j] = mcol[corner_indices[j]];
}
@@ -2064,13 +2055,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
void CustomData_update_typemap(CustomData *data)
{
- int i, lasttype = -1;
+ int lasttype = -1;
- for (i = 0; i < CD_NUMTYPES; i++) {
+ for (int i = 0; i < CD_NUMTYPES; i++) {
data->typemap[i] = -1;
}
- for (i = 0; i < data->totlayer; i++) {
+ for (int i = 0; i < data->totlayer; i++) {
const int type = data->layers[i].type;
if (type != lasttype) {
data->typemap[type] = i;
@@ -2097,18 +2088,16 @@ bool CustomData_merge(const struct CustomData *source,
{
/*const LayerTypeInfo *typeInfo;*/
CustomDataLayer *layer, *newlayer;
- void *data;
- int i, type, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0,
- flag = 0;
+ int lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
int number = 0, maxnumber = -1;
bool changed = false;
- for (i = 0; i < source->totlayer; i++) {
+ for (int i = 0; i < source->totlayer; i++) {
layer = &source->layers[i];
/*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/
- type = layer->type;
- flag = layer->flag;
+ int type = layer->type;
+ int flag = layer->flag;
if (type != lasttype) {
number = 0;
@@ -2136,6 +2125,7 @@ bool CustomData_merge(const struct CustomData *source,
continue;
}
+ void *data;
switch (alloctype) {
case CD_ASSIGN:
case CD_REFERENCE:
@@ -2518,8 +2508,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
/* Passing a layer-data to copy from with an alloctype that won't copy is
* most likely a bug */
- BLI_assert(!layerdata || (alloctype == CD_ASSIGN) || (alloctype == CD_DUPLICATE) ||
- (alloctype == CD_REFERENCE));
+ BLI_assert(!layerdata || ELEM(alloctype, CD_ASSIGN, CD_DUPLICATE, CD_REFERENCE));
if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
return &data->layers[CustomData_get_layer_index(data, type)];
@@ -2616,10 +2605,9 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
void *CustomData_add_layer(
CustomData *data, int type, eCDAllocType alloctype, void *layerdata, int totelem)
{
- CustomDataLayer *layer;
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
- layer = customData_add_layer__internal(
+ CustomDataLayer *layer = customData_add_layer__internal(
data, type, alloctype, layerdata, totelem, typeInfo->defaultname);
CustomData_update_typemap(data);
@@ -2638,9 +2626,8 @@ void *CustomData_add_layer_named(CustomData *data,
int totelem,
const char *name)
{
- CustomDataLayer *layer;
-
- layer = customData_add_layer__internal(data, type, alloctype, layerdata, totelem, name);
+ CustomDataLayer *layer = customData_add_layer__internal(
+ data, type, alloctype, layerdata, totelem, name);
CustomData_update_typemap(data);
if (layer) {
@@ -2828,12 +2815,10 @@ bool CustomData_is_referenced_layer(struct CustomData *data, int type)
void CustomData_free_temporary(CustomData *data, int totelem)
{
- CustomDataLayer *layer;
int i, j;
bool changed = false;
-
for (i = 0, j = 0; i < data->totlayer; i++) {
- layer = &data->layers[i];
+ CustomDataLayer *layer = &data->layers[i];
if (i != j) {
data->layers[j] = data->layers[i];
@@ -3681,10 +3666,8 @@ void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
{
- const LayerTypeInfo *typeInfo;
int offset = data->layers[n].offset;
-
- typeInfo = layerType_getInfo(data->layers[n].type);
+ const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
if (typeInfo->set_default) {
typeInfo->set_default(POINTER_OFFSET(*block, offset), 1);
@@ -4050,7 +4033,6 @@ void CustomData_bmesh_interp(CustomData *data,
return;
}
- int i, j;
void *source_buf[SOURCE_BUF_SIZE];
const void **sources = (const void **)source_buf;
@@ -4071,11 +4053,11 @@ void CustomData_bmesh_interp(CustomData *data,
}
/* interpolates a layer at a time */
- for (i = 0; i < data->totlayer; i++) {
+ for (int i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = &data->layers[i];
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if (typeInfo->interp) {
- for (j = 0; j < count; j++) {
+ for (int j = 0; j < count; j++) {
sources[j] = POINTER_OFFSET(src_blocks[j], layer->offset);
}
CustomData_bmesh_interp_n(
@@ -4465,7 +4447,6 @@ bool CustomData_layer_validate(CustomDataLayer *layer, const uint totitems, cons
void CustomData_layers__print(CustomData *data)
{
-
printf("{\n");
int i;
@@ -4520,10 +4501,7 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int
{
CustomDataExternal *external = data->external;
CustomDataLayer *layer;
- CDataFile *cdf;
- CDataFileLayer *blay;
char filename[FILE_MAX];
- const LayerTypeInfo *typeInfo;
int update = 0;
if (!external) {
@@ -4532,7 +4510,7 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int
for (int i = 0; i < data->totlayer; i++) {
layer = &data->layers[i];
- typeInfo = layerType_getInfo(layer->type);
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
/* pass */
@@ -4551,7 +4529,7 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int
customdata_external_filename(filename, id, external);
- cdf = cdf_create(CDF_TYPE_MESH);
+ CDataFile *cdf = cdf_create(CDF_TYPE_MESH);
if (!cdf_read_open(cdf, filename)) {
cdf_free(cdf);
CLOG_ERROR(&LOG, "Failed to read %s layer from %s.", layerType_getName(layer->type), filename);
@@ -4560,7 +4538,7 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int
for (int i = 0; i < data->totlayer; i++) {
layer = &data->layers[i];
- typeInfo = layerType_getInfo(layer->type);
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
/* pass */
@@ -4569,7 +4547,7 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int
/* pass */
}
else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) {
- blay = cdf_layer_find(cdf, layer->type, layer->name);
+ CDataFileLayer *blay = cdf_layer_find(cdf, layer->type, layer->name);
if (blay) {
if (cdf_read_layer(cdf, blay)) {
@@ -4596,10 +4574,6 @@ void CustomData_external_write(
CustomData *data, ID *id, CustomDataMask mask, int totelem, int free)
{
CustomDataExternal *external = data->external;
- CustomDataLayer *layer;
- CDataFile *cdf;
- CDataFileLayer *blay;
- const LayerTypeInfo *typeInfo;
int update = 0;
char filename[FILE_MAX];
@@ -4609,8 +4583,8 @@ void CustomData_external_write(
/* test if there is anything to write */
for (int i = 0; i < data->totlayer; i++) {
- layer = &data->layers[i];
- typeInfo = layerType_getInfo(layer->type);
+ CustomDataLayer *layer = &data->layers[i];
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
/* pass */
@@ -4628,11 +4602,11 @@ void CustomData_external_write(
CustomData_external_read(data, id, mask, totelem);
customdata_external_filename(filename, id, external);
- cdf = cdf_create(CDF_TYPE_MESH);
+ CDataFile *cdf = cdf_create(CDF_TYPE_MESH);
for (int i = 0; i < data->totlayer; i++) {
- layer = &data->layers[i];
- typeInfo = layerType_getInfo(layer->type);
+ CustomDataLayer *layer = &data->layers[i];
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) {
if (layer->flag & CD_FLAG_IN_MEMORY) {
@@ -4654,11 +4628,11 @@ void CustomData_external_write(
int i;
for (i = 0; i < data->totlayer; i++) {
- layer = &data->layers[i];
- typeInfo = layerType_getInfo(layer->type);
+ CustomDataLayer *layer = &data->layers[i];
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
- blay = cdf_layer_find(cdf, layer->type, layer->name);
+ CDataFileLayer *blay = cdf_layer_find(cdf, layer->type, layer->name);
if (cdf_write_layer(cdf, blay)) {
if (typeInfo->write(cdf, layer->data, totelem)) {
@@ -4682,8 +4656,8 @@ void CustomData_external_write(
}
for (i = 0; i < data->totlayer; i++) {
- layer = &data->layers[i];
- typeInfo = layerType_getInfo(layer->type);
+ CustomDataLayer *layer = &data->layers[i];
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
if (free) {
@@ -4703,15 +4677,13 @@ void CustomData_external_add(
CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename)
{
CustomDataExternal *external = data->external;
- CustomDataLayer *layer;
- int layer_index;
- layer_index = CustomData_get_active_layer_index(data, type);
+ int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) {
return;
}
- layer = &data->layers[layer_index];
+ CustomDataLayer *layer = &data->layers[layer_index];
if (layer->flag & CD_FLAG_EXTERNAL) {
return;
@@ -4835,8 +4807,6 @@ static void customdata_data_transfer_interp_generic(const CustomDataTransferLaye
cd_interp interp_cd = NULL;
cd_copy copy_cd = NULL;
- void *tmp_dst;
-
if (!sources) {
/* Not supported here, abort. */
return;
@@ -4853,7 +4823,7 @@ static void customdata_data_transfer_interp_generic(const CustomDataTransferLaye
copy_cd = type_info->copy;
}
- tmp_dst = MEM_mallocN(data_size, __func__);
+ void *tmp_dst = MEM_mallocN(data_size, __func__);
if (count > 1 && !interp_cd) {
if (data_flag) {
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 375792a02c2..58c050493c9 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -488,6 +488,7 @@ void BKE_displist_fill(ListBase *dispbase,
while (cont) {
int dl_flag_accum = 0;
+ int dl_rt_accum = 0;
cont = 0;
totvert = 0;
nextcol = 0;
@@ -535,6 +536,7 @@ void BKE_displist_fill(ListBase *dispbase,
}
}
dl_flag_accum |= dl->flag;
+ dl_rt_accum |= dl->rt;
}
}
@@ -544,6 +546,7 @@ void BKE_displist_fill(ListBase *dispbase,
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
dlnew->type = DL_INDEX3;
dlnew->flag = (dl_flag_accum & (DL_BACK_CURVE | DL_FRONT_CURVE));
+ dlnew->rt = (dl_rt_accum & CU_SMOOTH);
dlnew->col = colnr;
dlnew->nr = totvert;
dlnew->parts = tot;
@@ -1129,7 +1132,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
*
* The right solution would be to COW the Curve data block at the input of the modifier
* stack just like what the mesh modifier does.
- * */
+ */
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 811a27c9f3f..4a25b0e9d98 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -3419,7 +3419,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
break;
}
- /* Set output format, png in case exr isn't supported */
+ /* Set output format, PNG in case EXR isn't supported. */
#ifdef WITH_OPENEXR
if (format == R_IMF_IMTYPE_OPENEXR) { /* OpenEXR 32-bit float */
ibuf->ftype = IMB_FTYPE_OPENEXR;
@@ -5156,7 +5156,8 @@ static int dynamicPaint_prepareEffectStep(struct Depsgraph *depsgraph,
/* Init force data if required */
if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
- ListBase *effectors = BKE_effectors_create(depsgraph, ob, NULL, surface->effector_weights);
+ ListBase *effectors = BKE_effectors_create(
+ depsgraph, ob, NULL, surface->effector_weights, false);
/* allocate memory for force data (dir vector + strength) */
*force = MEM_mallocN(sizeof(float[4]) * sData->total_points, "PaintEffectForces");
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 13e9bb1bf24..4104b6080c5 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -270,11 +270,71 @@ void BKE_effector_relations_free(ListBase *lb)
}
}
+/* Check that the force field isn't disabled via its flags. */
+static bool is_effector_enabled(PartDeflect *pd, bool use_rotation)
+{
+ switch (pd->forcefield) {
+ case PFIELD_BOID:
+ case PFIELD_GUIDE:
+ return true;
+
+ case PFIELD_TEXTURE:
+ return (pd->flag & PFIELD_DO_LOCATION) != 0 && pd->tex != NULL;
+
+ default:
+ if (use_rotation) {
+ return (pd->flag & (PFIELD_DO_LOCATION | PFIELD_DO_ROTATION)) != 0;
+ }
+ else {
+ return (pd->flag & PFIELD_DO_LOCATION) != 0;
+ }
+ }
+}
+
+/* Check that the force field won't have zero effect due to strength settings. */
+static bool is_effector_nonzero_strength(PartDeflect *pd)
+{
+ if (pd->f_strength != 0.0f) {
+ return true;
+ }
+
+ if (pd->forcefield == PFIELD_TEXTURE) {
+ return false;
+ }
+
+ if (pd->f_noise > 0.0f || pd->f_flow != 0.0f) {
+ return true;
+ }
+
+ switch (pd->forcefield) {
+ case PFIELD_BOID:
+ case PFIELD_GUIDE:
+ return true;
+
+ case PFIELD_VORTEX:
+ return pd->shape != PFIELD_SHAPE_POINT;
+
+ case PFIELD_DRAG:
+ return pd->f_damp != 0.0f;
+
+ default:
+ return false;
+ }
+}
+
+/* Check if the force field will affect its user. */
+static bool is_effector_relevant(PartDeflect *pd, EffectorWeights *weights, bool use_rotation)
+{
+ return (weights->weight[pd->forcefield] != 0.0f) && is_effector_enabled(pd, use_rotation) &&
+ is_effector_nonzero_strength(pd);
+}
+
/* Create effective list of effectors from relations built beforehand. */
ListBase *BKE_effectors_create(Depsgraph *depsgraph,
Object *ob_src,
ParticleSystem *psys_src,
- EffectorWeights *weights)
+ EffectorWeights *weights,
+ bool use_rotation)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
ListBase *relations = DEG_get_effector_relations(depsgraph, weights->group);
@@ -299,7 +359,8 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph,
}
PartDeflect *pd = (relation->pd == relation->psys->part->pd) ? part->pd : part->pd2;
- if (weights->weight[pd->forcefield] == 0.0f) {
+
+ if (!is_effector_relevant(pd, weights, use_rotation)) {
continue;
}
@@ -310,7 +371,7 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph,
if (ob == ob_src) {
continue;
}
- if (weights->weight[ob->pd->forcefield] == 0.0f) {
+ if (!is_effector_relevant(ob->pd, weights, use_rotation)) {
continue;
}
if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) {
@@ -903,7 +964,9 @@ static void do_texture_effector(EffectorCache *eff,
madd_v3_v3fl(force, efd->nor, fac);
}
- add_v3_v3(total_force, force);
+ if (eff->pd->flag & PFIELD_DO_LOCATION) {
+ add_v3_v3(total_force, force);
+ }
}
static void do_physical_effector(EffectorCache *eff,
EffectorData *efd,
@@ -918,6 +981,7 @@ static void do_physical_effector(EffectorCache *eff,
float strength = pd->f_strength;
float damp = pd->f_damp;
float noise_factor = pd->f_noise;
+ float flow_falloff = efd->falloff;
if (noise_factor > 0.0f) {
strength += wind_func(rng, noise_factor);
@@ -1027,6 +1091,7 @@ static void do_physical_effector(EffectorCache *eff,
break;
case PFIELD_FLUIDFLOW:
zero_v3(force);
+ flow_falloff = 0;
#ifdef WITH_FLUID
if (pd->f_source) {
float density;
@@ -1036,8 +1101,7 @@ static void do_physical_effector(EffectorCache *eff,
influence *= density;
}
mul_v3_fl(force, influence);
- /* apply flow */
- madd_v3_v3fl(total_force, point->vel, -pd->f_flow * influence);
+ flow_falloff = influence;
}
}
#endif
@@ -1047,9 +1111,8 @@ static void do_physical_effector(EffectorCache *eff,
if (pd->flag & PFIELD_DO_LOCATION) {
madd_v3_v3fl(total_force, force, 1.0f / point->vel_to_sec);
- if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG, PFIELD_FLUIDFLOW) == 0 &&
- pd->f_flow != 0.0f) {
- madd_v3_v3fl(total_force, point->vel, -pd->f_flow * efd->falloff);
+ if (!ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG) && pd->f_flow != 0.0f) {
+ madd_v3_v3fl(total_force, point->vel, -pd->f_flow * flow_falloff);
}
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index ce710e2f7d4..8e1fa9732ea 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1110,7 +1110,7 @@ void fcurve_samples_to_keyframes(FCurve *fcu, const int start, const int end)
if (fcu->fpt == NULL) {
/* No data to unbake. */
- CLOG_ERROR(&LOG, "Error: Curve containts no baked keyframes");
+ CLOG_ERROR(&LOG, "Error: Curve contains no baked keyframes");
return;
}
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 59248e5f9f8..7fe009d51ca 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -3225,7 +3225,7 @@ static void update_effectors(
ListBase *effectors;
/* make sure smoke flow influence is 0.0f */
fds->effector_weights->weight[PFIELD_FLUIDFLOW] = 0.0f;
- effectors = BKE_effectors_create(depsgraph, ob, NULL, fds->effector_weights);
+ effectors = BKE_effectors_create(depsgraph, ob, NULL, fds->effector_weights, false);
if (effectors) {
/* Precalculate wind forces. */
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index df1dbaa905f..25a0259abe3 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -176,6 +176,8 @@ IDTypeInfo IDType_ID_VF = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/***************************** VFont *******************************/
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index a47a3dbc872..2eaef8fc121 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -19,6 +19,7 @@
#include "BKE_mesh.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_pointcloud.h"
+#include "BKE_volume.h"
#include "DNA_object_types.h"
@@ -52,6 +53,8 @@ GeometryComponent *GeometryComponent::create(GeometryComponentType component_typ
return new PointCloudComponent();
case GeometryComponentType::Instances:
return new InstancesComponent();
+ case GeometryComponentType::Volume:
+ return new VolumeComponent();
}
BLI_assert(false);
return nullptr;
@@ -202,6 +205,13 @@ const PointCloud *GeometrySet::get_pointcloud_for_read() const
return (component == nullptr) ? nullptr : component->get_for_read();
}
+/* Returns a read-only volume or null. */
+const Volume *GeometrySet::get_volume_for_read() const
+{
+ const VolumeComponent *component = this->get_component_for_read<VolumeComponent>();
+ return (component == nullptr) ? nullptr : component->get_for_read();
+}
+
/* Returns true when the geometry set has a point cloud component that has a point cloud. */
bool GeometrySet::has_pointcloud() const
{
@@ -216,6 +226,13 @@ bool GeometrySet::has_instances() const
return component != nullptr && component->instances_amount() >= 1;
}
+/* Returns true when the geometry set has a volume component that has a volume. */
+bool GeometrySet::has_volume() const
+{
+ const VolumeComponent *component = this->get_component_for_read<VolumeComponent>();
+ return component != nullptr && component->has_volume();
+}
+
/* Create a new geometry set that only contains the given mesh. */
GeometrySet GeometrySet::create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership)
{
@@ -263,6 +280,13 @@ PointCloud *GeometrySet::get_pointcloud_for_write()
return component.get_for_write();
}
+/* Returns a mutable volume or null. No ownership is transferred. */
+Volume *GeometrySet::get_volume_for_write()
+{
+ VolumeComponent &component = this->get_component_for_write<VolumeComponent>();
+ return component.get_for_write();
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -353,6 +377,17 @@ void MeshComponent::copy_vertex_group_names_from_object(const Object &object)
}
}
+const blender::Map<std::string, int> &MeshComponent::vertex_group_names() const
+{
+ return vertex_group_names_;
+}
+
+/* This is only exposed for the internal attribute API. */
+blender::Map<std::string, int> &MeshComponent::vertex_group_names()
+{
+ return vertex_group_names_;
+}
+
/* Get the mesh from this component. This method can be used by multiple threads at the same
* time. Therefore, the returned mesh should not be modified. No ownership is transferred. */
const Mesh *MeshComponent::get_for_read() const
@@ -545,6 +580,85 @@ bool InstancesComponent::is_empty() const
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Volume Component
+ * \{ */
+
+VolumeComponent::VolumeComponent() : GeometryComponent(GeometryComponentType::Volume)
+{
+}
+
+VolumeComponent::~VolumeComponent()
+{
+ this->clear();
+}
+
+GeometryComponent *VolumeComponent::copy() const
+{
+ VolumeComponent *new_component = new VolumeComponent();
+ if (volume_ != nullptr) {
+ new_component->volume_ = BKE_volume_copy_for_eval(volume_, false);
+ new_component->ownership_ = GeometryOwnershipType::Owned;
+ }
+ return new_component;
+}
+
+void VolumeComponent::clear()
+{
+ BLI_assert(this->is_mutable());
+ if (volume_ != nullptr) {
+ if (ownership_ == GeometryOwnershipType::Owned) {
+ BKE_id_free(nullptr, volume_);
+ }
+ volume_ = nullptr;
+ }
+}
+
+bool VolumeComponent::has_volume() const
+{
+ return volume_ != nullptr;
+}
+
+/* Clear the component and replace it with the new volume. */
+void VolumeComponent::replace(Volume *volume, GeometryOwnershipType ownership)
+{
+ BLI_assert(this->is_mutable());
+ this->clear();
+ volume_ = volume;
+ ownership_ = ownership;
+}
+
+/* Return the volume and clear the component. The caller takes over responsibility for freeing the
+ * volume (if the component was responsible before). */
+Volume *VolumeComponent::release()
+{
+ BLI_assert(this->is_mutable());
+ Volume *volume = volume_;
+ volume_ = nullptr;
+ return volume;
+}
+
+/* Get the volume from this component. This method can be used by multiple threads at the same
+ * time. Therefore, the returned volume should not be modified. No ownership is transferred. */
+const Volume *VolumeComponent::get_for_read() const
+{
+ return volume_;
+}
+
+/* Get the volume from this component. This method can only be used when the component is mutable,
+ * i.e. it is not shared. The returned volume can be modified. No ownership is transferred. */
+Volume *VolumeComponent::get_for_write()
+{
+ BLI_assert(this->is_mutable());
+ if (ownership_ == GeometryOwnershipType::ReadOnly) {
+ volume_ = BKE_volume_copy_for_eval(volume_, false);
+ ownership_ = GeometryOwnershipType::Owned;
+ }
+ return volume_;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name C API
* \{ */
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index f68a390db64..3d0152a6c7d 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -93,7 +93,33 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
/* make a copy of source layer and its data */
/* TODO here too could add unused flags... */
- bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
+ bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src, true, true);
+
+ /* 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 transfomed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
+ (!is_one_v3(gpl_dst->scale)));
+ if (transfomed) {
+ loc_eul_size_to_mat4(
+ gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
+ bool do_onion = ((gpl_dst->onion_flag & GP_LAYER_ONIONSKIN) != 0);
+ bGPDframe *init_gpf = (do_onion) ? gpl_dst->frames.first : gpl_dst->actframe;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDspoint *pt;
+ int i;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ mul_m4_v3(gpl_dst->layer_mat, &pt->x);
+ }
+ }
+ /* if not onion, exit loop. */
+ if (!do_onion) {
+ break;
+ }
+ }
+ }
+ }
BLI_addtail(&gpd_dst->layers, gpl_dst);
}
@@ -303,6 +329,8 @@ IDTypeInfo IDType_ID_GD = {
.blend_read_expand = greasepencil_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* ************************************************** */
@@ -581,7 +609,7 @@ bGPDframe *BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe)
}
/* Create a copy of the frame */
- new_frame = BKE_gpencil_frame_duplicate(gpl->actframe);
+ new_frame = BKE_gpencil_frame_duplicate(gpl->actframe, true);
/* Find frame to insert it before */
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
@@ -686,6 +714,14 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti
/* Enable always affected by scene lights. */
gpl->flag |= GP_LAYER_USE_LIGHTS;
+
+ /* Init transform. */
+ zero_v3(gpl->location);
+ zero_v3(gpl->rotation);
+ copy_v3_fl(gpl->scale, 1.0f);
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
/* make this one the active one */
if (setactive) {
BKE_gpencil_layer_active_set(gpd, gpl);
@@ -815,6 +851,7 @@ bGPDstroke *BKE_gpencil_stroke_new(int mat_idx, int totpoints, short thickness)
gps->mat_nr = mat_idx;
+ gps->dvert = NULL;
gps->editcurve = NULL;
return gps;
@@ -957,7 +994,7 @@ bGPDstroke *BKE_gpencil_stroke_duplicate(bGPDstroke *gps_src,
* \param gpf_src: Source grease pencil frame
* \return Pointer to new frame
*/
-bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src)
+bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src, const bool dup_strokes)
{
bGPDstroke *gps_dst = NULL;
bGPDframe *gpf_dst;
@@ -971,12 +1008,14 @@ bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src)
gpf_dst = MEM_dupallocN(gpf_src);
gpf_dst->prev = gpf_dst->next = NULL;
- /* copy strokes */
+ /* Copy strokes. */
BLI_listbase_clear(&gpf_dst->strokes);
- LISTBASE_FOREACH (bGPDstroke *, gps_src, &gpf_src->strokes) {
- /* make copy of source stroke */
- gps_dst = BKE_gpencil_stroke_duplicate(gps_src, true, true);
- BLI_addtail(&gpf_dst->strokes, gps_dst);
+ if (dup_strokes) {
+ LISTBASE_FOREACH (bGPDstroke *, gps_src, &gpf_src->strokes) {
+ /* make copy of source stroke */
+ gps_dst = BKE_gpencil_stroke_duplicate(gps_src, true, true);
+ BLI_addtail(&gpf_dst->strokes, gps_dst);
+ }
}
/* return new frame */
@@ -1010,7 +1049,9 @@ void BKE_gpencil_frame_copy_strokes(bGPDframe *gpf_src, struct bGPDframe *gpf_ds
* \param gpl_src: Source grease pencil layer
* \return Pointer to new layer
*/
-bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src)
+bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src,
+ const bool dup_frames,
+ const bool dup_strokes)
{
const bGPDframe *gpf_src;
bGPDframe *gpf_dst;
@@ -1035,14 +1076,16 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src)
/* copy frames */
BLI_listbase_clear(&gpl_dst->frames);
- for (gpf_src = gpl_src->frames.first; gpf_src; gpf_src = gpf_src->next) {
- /* make a copy of source frame */
- gpf_dst = BKE_gpencil_frame_duplicate(gpf_src);
- BLI_addtail(&gpl_dst->frames, gpf_dst);
-
- /* if source frame was the current layer's 'active' frame, reassign that too */
- if (gpf_src == gpl_dst->actframe) {
- gpl_dst->actframe = gpf_dst;
+ if (dup_frames) {
+ for (gpf_src = gpl_src->frames.first; gpf_src; gpf_src = gpf_src->next) {
+ /* make a copy of source frame */
+ gpf_dst = BKE_gpencil_frame_duplicate(gpf_src, dup_strokes);
+ BLI_addtail(&gpl_dst->frames, gpf_dst);
+
+ /* if source frame was the current layer's 'active' frame, reassign that too */
+ if (gpf_src == gpl_dst->actframe) {
+ gpl_dst->actframe = gpf_dst;
+ }
}
}
@@ -2519,7 +2562,7 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
int cfra)
{
bGPdata *gpd = (bGPdata *)ob->data;
- const bool is_multiedit = GPENCIL_MULTIEDIT_SESSIONS_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);
@@ -2541,6 +2584,11 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
continue;
}
+ /* If scale to 0 the layer must be invisible. */
+ if (is_zero_v3(gpl->scale)) {
+ continue;
+ }
+
/* Hide the layer if it's defined a view layer filter. This is used to
* generate renders, putting only selected GP layers for each View Layer.
* This is used only in final render and never in Viewport. */
@@ -2559,6 +2607,15 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
if (gpf == act_gpf || (gpf->flag & GP_FRAME_SELECT)) {
gpf->runtime.onion_id = 0;
+ if (do_onion) {
+ if (gpf->framenum < act_gpf->framenum) {
+ gpf->runtime.onion_id = -1;
+ }
+ else {
+ gpf->runtime.onion_id = 1;
+ }
+ }
+
if (sta_gpf == NULL) {
sta_gpf = gpf;
}
@@ -2759,10 +2816,10 @@ void BKE_gpencil_update_orig_pointers(const Object *ob_orig, const Object *ob_ev
* \param gpl: Grease pencil layer
* \param diff_mat: Result parent matrix
*/
-void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
- Object *obact,
- bGPDlayer *gpl,
- float diff_mat[4][4])
+void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph,
+ Object *obact,
+ bGPDlayer *gpl,
+ float diff_mat[4][4])
{
Object *ob_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obact) : obact;
Object *obparent = gpl->parent;
@@ -2771,11 +2828,10 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
/* if not layer parented, try with object parented */
if (obparent_eval == NULL) {
- if (ob_eval != NULL) {
- if (ob_eval->type == OB_GPENCIL) {
- copy_m4_m4(diff_mat, ob_eval->obmat);
- return;
- }
+ if ((ob_eval != NULL) && (ob_eval->type == OB_GPENCIL)) {
+ copy_m4_m4(diff_mat, ob_eval->obmat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
+ return;
}
/* not gpencil object */
unit_m4(diff_mat);
@@ -2785,6 +2841,7 @@ void BKE_gpencil_parent_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, diff_mat, gpl->layer_mat);
return;
}
if (gpl->partype == PARBONE) {
@@ -2800,6 +2857,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
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, diff_mat, gpl->layer_mat);
return;
}
@@ -2807,11 +2865,11 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
}
/**
- * Update parent matrix.
+ * Update parent matrix and local transforms.
* \param depsgraph: Depsgraph
* \param ob: Grease pencil object
*/
-void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
+void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
{
if (ob->type != OB_GPENCIL) {
return;
@@ -2820,31 +2878,50 @@ void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
bGPdata *gpd = (bGPdata *)ob->data;
float cur_mat[4][4];
+ bool changed = false;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- if ((gpl->parent != NULL) && (gpl->actframe != NULL)) {
- Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
- /* calculate new matrix */
- if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
- copy_m4_m4(cur_mat, ob_parent->obmat);
- }
- else if (gpl->partype == PARBONE) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
- if (pchan != NULL) {
- copy_m4_m4(cur_mat, ob->imat);
- mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
+ unit_m4(cur_mat);
+ if (gpl->actframe != NULL) {
+ if (gpl->parent != NULL) {
+ Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
+ /* calculate new matrix */
+ if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
+ copy_m4_m4(cur_mat, ob_parent->obmat);
}
- else {
- unit_m4(cur_mat);
+ else if (gpl->partype == PARBONE) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
+ if (pchan != NULL) {
+ copy_m4_m4(cur_mat, ob->imat);
+ mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
+ }
+ else {
+ unit_m4(cur_mat);
+ }
}
+ changed = !equals_m4m4(gpl->inverse, cur_mat);
}
+
+ /* Calc local layer transform. */
+ bool transfomed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
+ (!is_one_v3(gpl->scale)));
+ if (transfomed) {
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ }
+
/* only redo if any change */
- if (!equals_m4m4(gpl->inverse, cur_mat)) {
+ if (changed || transfomed) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
bGPDspoint *pt;
int i;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- mul_m4_v3(gpl->inverse, &pt->x);
- mul_m4_v3(cur_mat, &pt->x);
+ if (changed) {
+ mul_m4_v3(gpl->inverse, &pt->x);
+ mul_m4_v3(cur_mat, &pt->x);
+ }
+
+ if (transfomed) {
+ mul_m4_v3(gpl->layer_mat, &pt->x);
+ }
}
}
}
@@ -2872,4 +2949,26 @@ int BKE_gpencil_material_find_index_by_name_prefix(Object *ob, const char *name_
return -1;
}
+/* Create a hash with the list of selected frame number. */
+void BKE_gpencil_frame_selected_hash(bGPdata *gpd, struct GHash *r_list)
+{
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl_iter, &gpd->layers) {
+ if ((gpl != NULL) && (!is_multiedit) && (gpl != gpl_iter)) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_iter->frames) {
+ if (((gpf == gpl->actframe) && (!is_multiedit)) ||
+ ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (!BLI_ghash_lookup(r_list, POINTER_FROM_INT(gpf->framenum))) {
+ BLI_ghash_insert(r_list, POINTER_FROM_INT(gpf->framenum), gpf);
+ }
+ }
+ }
+ }
+}
+
/** \} */
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 981f5d50353..2ef85439a46 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -1684,11 +1684,12 @@ void BKE_gpencil_stroke_normal(const bGPDstroke *gps, float r_normal[3])
/* Stroke Simplify ------------------------------------- */
-/** Reduce a series of points to a simplified version, but
+/**
+ * Reduce a series of points to a simplified version, but
* maintains the general shape of the series
*
* Ramer - Douglas - Peucker algorithm
- * by http ://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
+ * by http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
* \param gpd: Grease pencil data-block
* \param gps: Grease pencil stroke
* \param epsilon: Epsilon value to define precision of the algorithm
@@ -3227,6 +3228,45 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
}
}
+/* Copy the stroke of the frame to all frames selected (except current). */
+void BKE_gpencil_stroke_copy_to_keyframes(
+ bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps, const bool tail)
+{
+ GHash *frame_list = BLI_ghash_int_new_ex(__func__, 64);
+ BKE_gpencil_frame_selected_hash(gpd, frame_list);
+
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, frame_list) {
+ int cfra = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
+
+ if (gpf->framenum != cfra) {
+ bGPDframe *gpf_new = BKE_gpencil_layer_frame_find(gpl, cfra);
+ if (gpf_new == NULL) {
+ gpf_new = BKE_gpencil_frame_addnew(gpl, cfra);
+ }
+
+ if (gpf_new == NULL) {
+ continue;
+ }
+
+ bGPDstroke *gps_new = BKE_gpencil_stroke_duplicate(gps, true, true);
+ if (gps_new == NULL) {
+ continue;
+ }
+
+ if (tail) {
+ BLI_addhead(&gpf_new->strokes, gps_new);
+ }
+ else {
+ BLI_addtail(&gpf_new->strokes, gps_new);
+ }
+ }
+ }
+
+ /* Free hash table. */
+ BLI_ghash_free(frame_list, NULL, NULL);
+}
+
/* Stroke Uniform Subdivide ------------------------------------- */
typedef struct tSamplePoint {
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 1be2cba31b5..8b12e1b5fca 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -701,13 +701,18 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
bGPdata *gpd_orig = (bGPdata *)ob_orig->data;
- /* Need check if some layer is parented. */
+ /* Need check if some layer is parented or transformed. */
bool do_parent = false;
+ bool do_transform = false;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
if (gpl->parent != NULL) {
do_parent = true;
break;
}
+ if ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) || (!is_one_v3(gpl->scale))) {
+ do_transform = true;
+ break;
+ }
}
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_eval);
@@ -715,7 +720,7 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
(ob->greasepencil_modifiers.first != NULL) &&
(!GPENCIL_SIMPLIFY_MODIF(scene)));
- if ((!do_modifiers) && (!do_parent)) {
+ if ((!do_modifiers) && (!do_parent) && (!do_transform)) {
return;
}
DEG_debug_print_eval(depsgraph, __func__, gpd_eval->id.name, gpd_eval);
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index a44b054e366..f76e5a73478 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -197,6 +197,8 @@ IDTypeInfo IDType_ID_HA = {
.blend_read_expand = hair_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
static void hair_random(Hair *hair)
diff --git a/source/blender/blenkernel/intern/icons.cc b/source/blender/blenkernel/intern/icons.cc
index cba1726a1b9..afb009b66cd 100644
--- a/source/blender/blenkernel/intern/icons.cc
+++ b/source/blender/blenkernel/intern/icons.cc
@@ -374,6 +374,7 @@ PreviewImage **BKE_previewimg_id_get_p(const ID *id)
ID_PRV_CASE(ID_GR, Collection);
ID_PRV_CASE(ID_SCE, Scene);
ID_PRV_CASE(ID_SCR, bScreen);
+ ID_PRV_CASE(ID_AC, bAction);
#undef ID_PRV_CASE
default:
break;
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index b0991f1d343..6b164e6bc50 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -92,11 +92,9 @@ IDProperty *IDP_NewIDPArray(const char *name)
IDProperty *IDP_CopyIDPArray(const IDProperty *array, const int flag)
{
/* don't use MEM_dupallocN because this may be part of an array */
- IDProperty *narray, *tmp;
-
BLI_assert(array->type == IDP_IDPARRAY);
- narray = MEM_mallocN(sizeof(IDProperty), __func__);
+ IDProperty *narray = MEM_mallocN(sizeof(IDProperty), __func__);
*narray = *array;
narray->data.pointer = MEM_dupallocN(array->data.pointer);
@@ -107,7 +105,7 @@ IDProperty *IDP_CopyIDPArray(const IDProperty *array, const int flag)
* then free it. this makes for more maintainable
* code than simply re-implementing the copy functions
* in this loop.*/
- tmp = IDP_CopyProperty_ex(GETPROP(narray, i), flag);
+ IDProperty *tmp = IDP_CopyProperty_ex(GETPROP(narray, i), flag);
memcpy(GETPROP(narray, i), tmp, sizeof(IDProperty));
MEM_freeN(tmp);
}
@@ -131,15 +129,13 @@ static void IDP_FreeIDPArray(IDProperty *prop, const bool do_id_user)
/* shallow copies item */
void IDP_SetIndexArray(IDProperty *prop, int index, IDProperty *item)
{
- IDProperty *old;
-
BLI_assert(prop->type == IDP_IDPARRAY);
if (index >= prop->len || index < 0) {
return;
}
- old = GETPROP(prop, index);
+ IDProperty *old = GETPROP(prop, index);
if (item != old) {
IDP_FreePropertyContent(old);
@@ -164,8 +160,6 @@ void IDP_AppendArray(IDProperty *prop, IDProperty *item)
void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
{
- int newsize;
-
BLI_assert(prop->type == IDP_IDPARRAY);
/* first check if the array buffer size has room */
@@ -200,7 +194,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
* system realloc().
* The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
*/
- newsize = newlen;
+ int newsize = newlen;
newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
prop->data.pointer = MEM_recallocN(prop->data.pointer, sizeof(IDProperty) * (size_t)newsize);
prop->len = newlen;
@@ -218,9 +212,8 @@ static void idp_resize_group_array(IDProperty *prop, int newlen, void *newarr)
/* bigger */
IDProperty **array = newarr;
IDPropertyTemplate val;
- int a;
- for (a = prop->len; a < newlen; a++) {
+ for (int a = prop->len; a < newlen; a++) {
val.i = 0; /* silence MSVC warning about uninitialized var when debugging */
array[a] = IDP_New(IDP_GROUP, &val, "IDP_ResizeArray group");
}
@@ -228,9 +221,8 @@ static void idp_resize_group_array(IDProperty *prop, int newlen, void *newarr)
else {
/* smaller */
IDProperty **array = prop->data.pointer;
- int a;
- for (a = newlen; a < prop->len; a++) {
+ for (int a = newlen; a < prop->len; a++) {
IDP_FreeProperty(array[a]);
}
}
@@ -239,7 +231,6 @@ static void idp_resize_group_array(IDProperty *prop, int newlen, void *newarr)
/*this function works for strings too!*/
void IDP_ResizeArray(IDProperty *prop, int newlen)
{
- int newsize;
const bool is_grow = newlen >= prop->len;
/* first check if the array buffer size has room */
@@ -257,7 +248,7 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
* system realloc().
* The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
*/
- newsize = newlen;
+ int newsize = newlen;
newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
if (is_grow == false) {
@@ -362,10 +353,8 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
static IDProperty *IDP_CopyString(const IDProperty *prop, const int flag)
{
- IDProperty *newp;
-
BLI_assert(prop->type == IDP_STRING);
- newp = idp_generic_copy(prop, flag);
+ IDProperty *newp = idp_generic_copy(prop, flag);
if (prop->data.pointer) {
newp->data.pointer = MEM_dupallocN(prop->data.pointer);
@@ -379,10 +368,8 @@ static IDProperty *IDP_CopyString(const IDProperty *prop, const int flag)
void IDP_AssignString(IDProperty *prop, const char *st, int maxlen)
{
- int stlen;
-
BLI_assert(prop->type == IDP_STRING);
- stlen = (int)strlen(st);
+ int stlen = (int)strlen(st);
if (maxlen > 0 && maxlen < stlen) {
stlen = maxlen;
}
@@ -400,11 +387,9 @@ void IDP_AssignString(IDProperty *prop, const char *st, int maxlen)
void IDP_ConcatStringC(IDProperty *prop, const char *st)
{
- int newlen;
-
BLI_assert(prop->type == IDP_STRING);
- newlen = prop->len + (int)strlen(st);
+ int newlen = prop->len + (int)strlen(st);
/* we have to remember that prop->len includes the null byte for strings.
* so there's no need to add +1 to the resize function.*/
IDP_ResizeArray(prop, newlen);
@@ -413,13 +398,11 @@ void IDP_ConcatStringC(IDProperty *prop, const char *st)
void IDP_ConcatString(IDProperty *str1, IDProperty *append)
{
- int newlen;
-
BLI_assert(append->type == IDP_STRING);
/* since ->len for strings includes the NULL byte, we have to subtract one or
* we'll get an extra null byte after each concatenation operation.*/
- newlen = str1->len + append->len - 1;
+ int newlen = str1->len + append->len - 1;
IDP_ResizeArray(str1, newlen);
strcat(str1->data.pointer, append->data.pointer);
}
@@ -440,10 +423,8 @@ void IDP_FreeString(IDProperty *prop)
static IDProperty *IDP_CopyID(const IDProperty *prop, const int flag)
{
- IDProperty *newp;
-
BLI_assert(prop->type == IDP_ID);
- newp = idp_generic_copy(prop, flag);
+ IDProperty *newp = idp_generic_copy(prop, flag);
newp->data.pointer = prop->data.pointer;
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
@@ -479,14 +460,12 @@ void IDP_AssignID(IDProperty *prop, ID *id, const int flag)
*/
static IDProperty *IDP_CopyGroup(const IDProperty *prop, const int flag)
{
- IDProperty *newp, *link;
-
BLI_assert(prop->type == IDP_GROUP);
- newp = idp_generic_copy(prop, flag);
+ IDProperty *newp = idp_generic_copy(prop, flag);
newp->len = prop->len;
newp->subtype = prop->subtype;
- for (link = prop->data.group.first; link; link = link->next) {
+ LISTBASE_FOREACH (IDProperty *, link, &prop->data.group) {
BLI_addtail(&newp->data.group, IDP_CopyProperty_ex(link, flag));
}
@@ -497,13 +476,11 @@ static IDProperty *IDP_CopyGroup(const IDProperty *prop, const int flag)
* When values name and types match, copy the values, else ignore */
void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src)
{
- IDProperty *other, *prop;
-
BLI_assert(dest->type == IDP_GROUP);
BLI_assert(src->type == IDP_GROUP);
- for (prop = src->data.group.first; prop; prop = prop->next) {
- other = BLI_findstring(&dest->data.group, prop->name, offsetof(IDProperty, name));
+ LISTBASE_FOREACH (IDProperty *, prop, &src->data.group) {
+ IDProperty *other = BLI_findstring(&dest->data.group, prop->name, offsetof(IDProperty, name));
if (other && prop->type == other->type) {
switch (prop->type) {
case IDP_INT:
@@ -526,12 +503,9 @@ void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src)
void IDP_SyncGroupTypes(IDProperty *dest, const IDProperty *src, const bool do_arraylen)
{
- IDProperty *prop_dst, *prop_dst_next;
- const IDProperty *prop_src;
-
- for (prop_dst = dest->data.group.first; prop_dst; prop_dst = prop_dst_next) {
- prop_dst_next = prop_dst->next;
- if ((prop_src = IDP_GetPropertyFromGroup((IDProperty *)src, prop_dst->name))) {
+ LISTBASE_FOREACH_MUTABLE (IDProperty *, prop_dst, &src->data.group) {
+ const IDProperty *prop_src = IDP_GetPropertyFromGroup((IDProperty *)src, prop_dst->name);
+ if (prop_src != NULL) {
/* check of we should replace? */
if ((prop_dst->type != prop_src->type || prop_dst->subtype != prop_src->subtype) ||
(do_arraylen && ELEM(prop_dst->type, IDP_ARRAY, IDP_IDPARRAY) &&
@@ -554,12 +528,11 @@ void IDP_SyncGroupTypes(IDProperty *dest, const IDProperty *src, const bool do_a
*/
void IDP_ReplaceGroupInGroup(IDProperty *dest, const IDProperty *src)
{
- IDProperty *loop, *prop;
-
BLI_assert(dest->type == IDP_GROUP);
BLI_assert(src->type == IDP_GROUP);
- for (prop = src->data.group.first; prop; prop = prop->next) {
+ LISTBASE_FOREACH (IDProperty *, prop, &src->data.group) {
+ IDProperty *loop;
for (loop = dest->data.group.first; loop; loop = loop->next) {
if (STREQ(loop->name, prop->name)) {
BLI_insertlinkreplace(&dest->data.group, loop, IDP_CopyProperty(prop));
@@ -612,13 +585,11 @@ void IDP_MergeGroup_ex(IDProperty *dest,
const bool do_overwrite,
const int flag)
{
- IDProperty *prop;
-
BLI_assert(dest->type == IDP_GROUP);
BLI_assert(src->type == IDP_GROUP);
if (do_overwrite) {
- for (prop = src->data.group.first; prop; prop = prop->next) {
+ LISTBASE_FOREACH (IDProperty *, prop, &src->data.group) {
if (prop->type == IDP_GROUP) {
IDProperty *prop_exist = IDP_GetPropertyFromGroup(dest, prop->name);
@@ -633,7 +604,7 @@ void IDP_MergeGroup_ex(IDProperty *dest,
}
}
else {
- for (prop = src->data.group.first; prop; prop = prop->next) {
+ LISTBASE_FOREACH (IDProperty *, prop, &src->data.group) {
IDProperty *prop_exist = IDP_GetPropertyFromGroup(dest, prop->name);
if (prop_exist != NULL) {
if (prop->type == IDP_GROUP) {
@@ -741,10 +712,9 @@ IDProperty *IDP_GetPropertyTypeFromGroup(const IDProperty *prop, const char *nam
* direct data. */
static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user)
{
- IDProperty *loop;
-
BLI_assert(prop->type == IDP_GROUP);
- for (loop = prop->data.group.first; loop; loop = loop->next) {
+
+ LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
IDP_FreePropertyContent_ex(loop, do_id_user);
}
BLI_freelistN(&prop->data.group);
@@ -863,14 +833,12 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
}
return false;
case IDP_GROUP: {
- IDProperty *link1, *link2;
-
if (is_strict && prop1->len != prop2->len) {
return false;
}
- for (link1 = prop1->data.group.first; link1; link1 = link1->next) {
- link2 = IDP_GetPropertyFromGroup(prop2, link1->name);
+ LISTBASE_FOREACH (IDProperty *, link1, &prop1->data.group) {
+ IDProperty *link2 = IDP_GetPropertyFromGroup(prop2, link1->name);
if (!IDP_EqualsProperties_ex(link1, link2, is_strict)) {
return false;
@@ -1158,11 +1126,10 @@ static void IDP_WriteIDPArray(const IDProperty *prop, BlendWriter *writer)
/*REMEMBER to set totalen to len in the linking code!!*/
if (prop->data.pointer) {
const IDProperty *array = prop->data.pointer;
- int a;
BLO_write_struct_array(writer, IDProperty, prop->len, array);
- for (a = 0; a < prop->len; a++) {
+ for (int a = 0; a < prop->len; a++) {
IDP_WriteProperty_OnlyData(&array[a], writer);
}
}
@@ -1176,9 +1143,7 @@ static void IDP_WriteString(const IDProperty *prop, BlendWriter *writer)
static void IDP_WriteGroup(const IDProperty *prop, BlendWriter *writer)
{
- IDProperty *loop;
-
- for (loop = prop->data.group.first; loop; loop = loop->next) {
+ LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
IDP_BlendWrite(writer, loop);
}
}
@@ -1212,13 +1177,11 @@ static void IDP_DirectLinkProperty(IDProperty *prop, BlendDataReader *reader);
static void IDP_DirectLinkIDPArray(IDProperty *prop, BlendDataReader *reader)
{
- IDProperty *array;
-
/* since we didn't save the extra buffer, set totallen to len */
prop->totallen = prop->len;
BLO_read_data_address(reader, &prop->data.pointer);
- array = (IDProperty *)prop->data.pointer;
+ IDProperty *array = (IDProperty *)prop->data.pointer;
/* note!, idp-arrays didn't exist in 2.4x, so the pointer will be cleared
* there's not really anything we can do to correct this, at least don't crash */
@@ -1234,14 +1197,12 @@ static void IDP_DirectLinkIDPArray(IDProperty *prop, BlendDataReader *reader)
static void IDP_DirectLinkArray(IDProperty *prop, BlendDataReader *reader)
{
- IDProperty **array;
-
/* since we didn't save the extra buffer, set totallen to len */
prop->totallen = prop->len;
if (prop->subtype == IDP_GROUP) {
BLO_read_pointer_array(reader, &prop->data.pointer);
- array = prop->data.pointer;
+ IDProperty **array = prop->data.pointer;
for (int i = 0; i < prop->len; i++) {
IDP_DirectLinkProperty(array[i], reader);
@@ -1266,12 +1227,11 @@ static void IDP_DirectLinkString(IDProperty *prop, BlendDataReader *reader)
static void IDP_DirectLinkGroup(IDProperty *prop, BlendDataReader *reader)
{
ListBase *lb = &prop->data.group;
- IDProperty *loop;
BLO_read_list(reader, lb);
/*Link child id properties now*/
- for (loop = prop->data.group.first; loop; loop = loop->next) {
+ LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
IDP_DirectLinkProperty(loop, reader);
}
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index ab57d14d2cf..10f15519ea4 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -338,6 +338,8 @@ IDTypeInfo IDType_ID_IM = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* prototypes */
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 1ab6e61e20e..d43a0cb3813 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -200,6 +200,8 @@ IDTypeInfo IDType_ID_IP = {
.blend_read_expand = ipo_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* *************************************************** */
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 433d64a5927..540337b84b3 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -223,6 +223,8 @@ IDTypeInfo IDType_ID_KE = {
.blend_read_expand = shapekey_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
#define KEY_MODE_DUMMY 0 /* use where mode isn't checked for */
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 74f78106be5..3d3ade1a529 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -205,6 +205,8 @@ IDTypeInfo IDType_ID_LT = {
.blend_read_expand = lattice_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
int BKE_lattice_index_from_uvw(Lattice *lt, const int u, const int v, const int w)
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 13f76b46570..54c2f5f5565 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -112,6 +112,8 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* GS reads the memory pointed at in a specific ordering.
@@ -1793,32 +1795,31 @@ static void library_make_local_copying_check(ID *id,
return; /* Already checked, nothing else to do. */
}
- MainIDRelationsEntry *entry = BLI_ghash_lookup(id_relations->id_used_to_user, id);
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(id_relations->relations_from_pointers, id);
BLI_gset_insert(loop_tags, id);
- for (; entry != NULL; entry = entry->next) {
-
- /* Used_to_user stores ID pointer, not pointer to ID pointer. */
- ID *par_id = (ID *)entry->id_pointer;
-
+ for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != NULL;
+ from_id_entry = from_id_entry->next) {
/* Our oh-so-beloved 'from' pointers... Those should always be ignored here, since the actual
* relation we want to check is in the other way around. */
- if (entry->usage_flag & IDWALK_CB_LOOPBACK) {
+ if (from_id_entry->usage_flag & IDWALK_CB_LOOPBACK) {
continue;
}
+ ID *from_id = from_id_entry->id_pointer.from;
+
/* Shape-keys are considered 'private' to their owner ID here, and never tagged
* (since they cannot be linked), so we have to switch effective parent to their owner.
*/
- if (GS(par_id->name) == ID_KE) {
- par_id = ((Key *)par_id)->from;
+ if (GS(from_id->name) == ID_KE) {
+ from_id = ((Key *)from_id)->from;
}
- if (par_id->lib == NULL) {
+ if (from_id->lib == NULL) {
/* Local user, early out to avoid some gset querying... */
continue;
}
- if (!BLI_gset_haskey(done_ids, par_id)) {
- if (BLI_gset_haskey(loop_tags, par_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
* (since all of them have non-local users, they would all be duplicated,
@@ -1827,10 +1828,10 @@ static void library_make_local_copying_check(ID *id,
continue;
}
/* Else, recursively check that user ID. */
- library_make_local_copying_check(par_id, loop_tags, id_relations, done_ids);
+ library_make_local_copying_check(from_id, loop_tags, id_relations, done_ids);
}
- if (par_id->tag & LIB_TAG_DOIT) {
+ if (from_id->tag & LIB_TAG_DOIT) {
/* This user will be fully local in future, so far so good,
* nothing to do here but check next user. */
}
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index e4094c48368..602c560cedd 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -368,183 +368,249 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
return success;
}
-static bool lib_override_hierarchy_recursive_tag(Main *bmain,
- ID *id,
- const uint tag,
- const uint missing_tag,
- Library *override_group_lib_reference)
+typedef struct LibOverrideGroupTagData {
+ Main *bmain;
+ ID *id_root;
+ uint tag;
+ uint missing_tag;
+} LibOverrideGroupTagData;
+
+/* Tag all IDs in dependency relationships within an override hierarchy/group.
+ *
+ * Requires existing `Main.relations`.
+ *
+ * Note: this is typically called to complete `lib_override_linked_group_tag()`.
+ */
+static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTagData *data)
{
- void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id);
- if (entry_vp == NULL) {
- /* Already processed. */
- return (id->tag & tag) != 0;
- }
+ Main *bmain = data->bmain;
+ ID *id = data->id_root;
- /* Note: in case some reference ID is missing from linked data (and therefore its override uses
- * a placeholder as reference), use `missing_tag` instead of `tag` for this override. */
- if (override_group_lib_reference != NULL && ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
- id->override_library->reference->lib == override_group_lib_reference) {
- if (id->override_library->reference->tag & LIB_TAG_MISSING) {
- id->tag |= missing_tag;
- }
- else {
- id->tag |= tag;
- }
- }
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers, id);
+ BLI_assert(entry != NULL);
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
+ /* This ID has already been processed. */
+ return (*(uint *)&id->tag & data->tag) != 0;
+ }
/* This way we won't process again that ID, should we encounter it again through another
- * relationship hierarchy.
- * Note that this does not free any memory from relations, so we can still use the entries.
- */
- BKE_main_relations_ID_remove(bmain, id);
+ * relationship hierarchy. */
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
- for (MainIDRelationsEntry *entry = *entry_vp; entry != NULL; entry = entry->next) {
- if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
+ for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
+ to_id_entry = to_id_entry->next) {
+ if ((to_id_entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
/* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
* actual dependencies. */
continue;
}
/* We only consider IDs from the same library. */
- if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
- if (lib_override_hierarchy_recursive_tag(
- bmain, *entry->id_pointer, tag, missing_tag, override_group_lib_reference) &&
- override_group_lib_reference == NULL) {
- id->tag |= tag;
+ ID *to_id = *to_id_entry->id_pointer.to;
+ if (to_id != NULL && to_id->lib == id->lib) {
+ LibOverrideGroupTagData sub_data = *data;
+ sub_data.id_root = to_id;
+ if (lib_override_hierarchy_dependencies_recursive_tag(&sub_data)) {
+ id->tag |= data->tag;
}
}
}
- return (id->tag & tag) != 0;
+ return (*(uint *)&id->tag & data->tag) != 0;
}
-/**
- * Tag all IDs in given \a bmain that are being used by given \a id_root ID or its dependencies,
- * recursively.
- * It detects and tag only chains of dependencies marked at both ends by given tag.
- *
- * This will include all local IDs, and all IDs from the same library as the \a id_root.
- *
- * \param id_root: The root of the hierarchy of dependencies to be tagged.
- * \param do_create_main_relashionships: Whether main relations needs to be created or already
- * exist (in any case, they will be freed by this function).
- */
-void BKE_lib_override_library_dependencies_tag(Main *bmain,
- ID *id_root,
- const uint tag,
- const bool do_create_main_relashionships)
+static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *data)
{
- if (do_create_main_relashionships) {
- BKE_main_relations_create(bmain, 0);
+ Main *bmain = data->bmain;
+ ID *id_owner = data->id_root;
+ BLI_assert(ID_IS_LINKED(id_owner));
+ const uint tag = data->tag;
+ const uint missing_tag = data->missing_tag;
+
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers,
+ id_owner);
+ BLI_assert(entry != NULL);
+
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
+ /* This ID has already been processed. */
+ return;
}
+ /* This way we won't process again that ID, should we encounter it again through another
+ * relationship hierarchy. */
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
+
+ for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
+ to_id_entry = to_id_entry->next) {
+ if ((to_id_entry->usage_flag &
+ (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers), nor
+ * override references or embedded ID pointers, as actual dependencies. */
+ continue;
+ }
- /* We tag all intermediary data-blocks in-between two overridden ones (e.g. if a shape-key
- * has a driver using an armature object's bone, we need to override the shape-key/obdata,
- * the objects using them, etc.) */
- lib_override_hierarchy_recursive_tag(bmain, id_root, tag, 0, NULL);
+ ID *to_id = *to_id_entry->id_pointer.to;
+ if (ELEM(to_id, NULL, id_owner)) {
+ continue;
+ }
+ /* We only consider IDs from the same library. */
+ if (to_id->lib != id_owner->lib) {
+ continue;
+ }
+ BLI_assert(ID_IS_LINKED(to_id));
+
+ /* We tag all collections and objects for override. And we also tag all other data-blocks which
+ * would use one of those.
+ * Note: missing IDs (aka placeholders) are never overridden. */
+ if (ELEM(GS(to_id->name), ID_OB, ID_GR)) {
+ if ((to_id->tag & LIB_TAG_MISSING)) {
+ to_id->tag |= missing_tag;
+ }
+ else {
+ to_id->tag |= tag;
+ }
+ }
- BKE_main_relations_free(bmain);
+ /* Recursively process the dependencies. */
+ LibOverrideGroupTagData sub_data = *data;
+ sub_data.id_root = to_id;
+ lib_override_linked_group_tag_recursive(&sub_data);
+ }
}
-/**
- * Tag all IDs in given \a bmain that are part of the same \a id_root liboverride ID group.
- * That is, all other liboverride IDs (in)directly used by \a is_root one, and sharing the same
- * library for their reference IDs.
+/* This will tag at least all 'boundary' linked IDs for a potential override group.
+ *
+ * Requires existing `Main.relations`.
*
- * \param id_root: The root of the hierarchy of liboverride dependencies to be tagged.
- * \param do_create_main_relashionships: Whether main relations needs to be created or already
- * exist (in any case, they will be freed by this function).
+ * Note that you will then need to call #lib_override_hierarchy_dependencies_recursive_tag to
+ * complete tagging of all dependencies within the override group.
+ *
+ * We currently only consider Collections and Objects (that are not used as bone shapes) as valid
+ * boundary IDs to define an override group.
*/
-void BKE_lib_override_library_override_group_tag(Main *bmain,
- ID *id_root,
- const uint tag,
- const uint missing_tag,
- const bool do_create_main_relashionships)
+static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
{
- if (do_create_main_relashionships) {
- BKE_main_relations_create(bmain, 0);
+ Main *bmain = data->bmain;
+ ID *id_root = data->id_root;
+
+ if ((id_root->tag & LIB_TAG_MISSING)) {
+ id_root->tag |= data->missing_tag;
+ }
+ else {
+ id_root->tag |= data->tag;
}
- /* We tag all liboverride data-blocks from the same library as reference one,
- * being used by the root ID. */
- lib_override_hierarchy_recursive_tag(
- bmain, id_root, tag, missing_tag, id_root->override_library->reference->lib);
+ if (ELEM(GS(id_root->name), ID_OB, ID_GR)) {
+ /* Tag all collections and objects. */
+ lib_override_linked_group_tag_recursive(data);
- BKE_main_relations_free(bmain);
+ /* Then, we remove (untag) bone shape objects, you shall never want to directly/explicitly
+ * override those. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & data->tag)) {
+ for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
+ if (pchan->custom != NULL) {
+ pchan->custom->id.tag &= ~(data->tag | data->missing_tag);
+ }
+ }
+ }
+ }
+ }
}
-static int lib_override_library_make_tag_ids_cb(LibraryIDLinkCallbackData *cb_data)
+static void lib_override_local_group_tag_recursive(LibOverrideGroupTagData *data)
{
- if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK)) {
- return IDWALK_RET_STOP_RECURSION;
+ Main *bmain = data->bmain;
+ ID *id_owner = data->id_root;
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY(id_owner));
+ const uint tag = data->tag;
+ const uint missing_tag = data->missing_tag;
+
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers,
+ id_owner);
+ BLI_assert(entry != NULL);
+
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
+ /* This ID has already been processed. */
+ return;
}
+ /* This way we won't process again that ID, should we encounter it again through another
+ * relationship hierarchy. */
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
+
+ for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
+ to_id_entry = to_id_entry->next) {
+ if ((to_id_entry->usage_flag &
+ (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers), nor
+ * override references or embedded ID pointers, as actual dependencies. */
+ continue;
+ }
- ID *id_root = cb_data->user_data;
- Library *library_root = id_root->lib;
- ID *id = *cb_data->id_pointer;
- ID *id_owner = cb_data->id_owner;
-
- BLI_assert(id_owner == cb_data->id_self);
+ ID *to_id = *to_id_entry->id_pointer.to;
+ if (ELEM(to_id, NULL, id_owner)) {
+ continue;
+ }
+ if (!ID_IS_OVERRIDE_LIBRARY(to_id) || ID_IS_LINKED(to_id)) {
+ continue;
+ }
- if (ELEM(id, NULL, id_owner)) {
- return IDWALK_RET_NOP;
- }
+ /* Do not tag 'virtual' overrides (shape keys here, as we already rejected embedded case
+ * above). */
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(to_id)) {
+ Library *reference_lib = NULL;
+ if (GS(id_owner->name) == ID_KE) {
+ reference_lib = ((Key *)id_owner)->from->override_library->reference->lib;
+ }
+ else {
+ reference_lib = id_owner->override_library->reference->lib;
+ }
+ if (to_id->override_library->reference->lib != reference_lib) {
+ /* We do not override data-blocks from other libraries, nor do we process them. */
+ continue;
+ }
- BLI_assert(id->lib != NULL);
- BLI_assert(id_owner->lib == library_root);
+ if (to_id->override_library->reference->tag & LIB_TAG_MISSING) {
+ to_id->tag |= missing_tag;
+ }
+ else {
+ to_id->tag |= tag;
+ }
+ }
- if (id->tag & LIB_TAG_DOIT) {
- /* Already processed and tagged, nothing else to do here. */
- return IDWALK_RET_STOP_RECURSION;
+ /* Recursively process the dependencies. */
+ LibOverrideGroupTagData sub_data = *data;
+ sub_data.id_root = to_id;
+ lib_override_local_group_tag_recursive(&sub_data);
}
+}
- if (id->lib != library_root) {
- /* We do not override data-blocks from other libraries, nor do we process them. */
- return IDWALK_RET_STOP_RECURSION;
- }
+/* This will tag all override IDs of an override group defined by the given `id_root`. */
+static void lib_override_local_group_tag(LibOverrideGroupTagData *data)
+{
+ ID *id_root = data->id_root;
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root) && !ID_IS_LINKED(id_root));
- /* We tag all collections and objects for override. And we also tag all other data-blocks which
- * would use one of those.
- * Note: missing IDs (aka placeholders) are never overridden. */
- if (ELEM(GS(id->name), ID_OB, ID_GR) && !(id->tag & LIB_TAG_MISSING)) {
- id->tag |= LIB_TAG_DOIT;
+ if ((id_root->override_library->reference->tag & LIB_TAG_MISSING)) {
+ id_root->tag |= data->missing_tag;
+ }
+ else {
+ id_root->tag |= data->tag;
}
- return IDWALK_RET_NOP;
+ /* Tag all local overrides in id_root's group. */
+ lib_override_local_group_tag_recursive(data);
}
static bool lib_override_library_create_do(Main *bmain, ID *id_root)
{
- id_root->tag |= LIB_TAG_DOIT;
-
BKE_main_relations_create(bmain, 0);
+ LibOverrideGroupTagData data = {
+ .bmain = bmain, .id_root = id_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING};
+ lib_override_linked_group_tag(&data);
- if (ELEM(GS(id_root->name), ID_OB, ID_GR)) {
- /* Tag all collections and objects. */
- BKE_library_foreach_ID_link(bmain,
- id_root,
- lib_override_library_make_tag_ids_cb,
- id_root,
- IDWALK_READONLY | IDWALK_RECURSE);
-
- /* Then, we remove (untag) bone shape objects, you shall never want to override those
- * (hopefully). */
- LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
- if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & LIB_TAG_DOIT)) {
- for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
- if (pchan->custom != NULL) {
- pchan->custom->id.tag &= ~LIB_TAG_DOIT;
- }
- }
- }
- }
- }
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
+ lib_override_hierarchy_dependencies_recursive_tag(&data);
- /* Now tag all non-object/collection IDs 'in-between' two tagged ones, as those are part of an
- * override chain and therefore also need to be overridden.
- * One very common cases are e.g. drivers on geometry or materials of an overridden object, that
- * are using another overridden object as parameter. */
- /* Note that this call will also free the main relations data we created above. */
- BKE_lib_override_library_dependencies_tag(bmain, id_root, LIB_TAG_DOIT, false);
+ BKE_main_relations_free(bmain);
return BKE_lib_override_library_create_from_tag(bmain);
}
@@ -737,14 +803,21 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
{
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
- /* Tag all collections and objects, as well as other IDs using them. */
- id_root->tag |= LIB_TAG_DOIT;
ID *id_root_reference = id_root->override_library->reference;
- /* Make a mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides, and tag
- * linked reference ones to be overridden again. */
- BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_MISSING, true);
+ BKE_main_relations_create(bmain, 0);
+ LibOverrideGroupTagData data = {
+ .bmain = bmain, .id_root = id_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING};
+ lib_override_local_group_tag(&data);
+
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
+ data.id_root = id_root_reference;
+ lib_override_linked_group_tag(&data);
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
+ lib_override_hierarchy_dependencies_recursive_tag(&data);
+
+ /* Make a mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides. */
GHash *linkedref_to_old_override = BLI_ghash_new(
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
ID *id;
@@ -755,17 +828,45 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
* same linked ID in a same hierarchy. */
if (!BLI_ghash_haskey(linkedref_to_old_override, id->override_library->reference)) {
BLI_ghash_insert(linkedref_to_old_override, id->override_library->reference, id);
- id->override_library->reference->tag |= LIB_TAG_DOIT;
+ if ((id->override_library->reference->tag & LIB_TAG_DOIT) == 0) {
+ /* We have an override, but now it does not seem to be necessary to override that ID
+ * anymore. Check if there are some actual overrides from the user, otherwise assume
+ * that we can get rid of this local override. */
+ LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) {
+ if (op->rna_prop_type != PROP_POINTER) {
+ id->override_library->reference->tag |= LIB_TAG_DOIT;
+ break;
+ }
+
+ bool do_break = false;
+ LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
+ if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) {
+ id->override_library->reference->tag |= LIB_TAG_DOIT;
+ do_break = true;
+ break;
+ }
+ }
+ if (do_break) {
+ break;
+ }
+ }
+ }
}
}
}
FOREACH_MAIN_ID_END;
+ /* Code above may have added some tags, we need to update this too. */
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
+ lib_override_hierarchy_dependencies_recursive_tag(&data);
+
+ BKE_main_relations_free(bmain);
+
/* Make new override from linked data. */
/* Note that this call also remaps all pointers of tagged IDs from old override IDs to new
* override IDs (including within the old overrides themselves, since those are tagged too
* above). */
- const bool success = lib_override_library_create_do(bmain, id_root_reference);
+ const bool success = BKE_lib_override_library_create_from_tag(bmain);
if (!success) {
return success;
@@ -828,6 +929,23 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
RNA_id_pointer_create(id_override_old, &rnaptr_src);
RNA_id_pointer_create(id_override_new, &rnaptr_dst);
+ /* We remove any operation tagged with `IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE`,
+ * that way the potentially new pointer will be properly kept, when old one is still valid
+ * too (typical case: assigning new ID to some usage, while old one remains used elsewhere
+ * in the override hierarchy). */
+ LISTBASE_FOREACH_MUTABLE (
+ IDOverrideLibraryProperty *, op, &id_override_new->override_library->properties) {
+ LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
+ if (opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) {
+ lib_override_library_property_operation_clear(opop);
+ BLI_freelinkN(&op->operations, opop);
+ }
+ }
+ if (BLI_listbase_is_empty(&op->operations)) {
+ BKE_lib_override_library_property_delete(id_override_new->override_library, op);
+ }
+ }
+
RNA_struct_override_apply(
bmain, &rnaptr_dst, &rnaptr_src, NULL, id_override_new->override_library);
}
@@ -896,11 +1014,13 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
{
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
- /* Tag all collections and objects, as well as other IDs using them. */
- id_root->tag |= LIB_TAG_DOIT;
-
/* Tag all library overrides in the chains of dependencies from the given root one. */
- BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, LIB_TAG_DOIT, true);
+ BKE_main_relations_create(bmain, 0);
+ LibOverrideGroupTagData data = {
+ .bmain = bmain, .id_root = id_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING};
+ lib_override_local_group_tag(&data);
+
+ BKE_main_relations_free(bmain);
ID *id;
FOREACH_MAIN_ID_BEGIN (bmain, id) {
@@ -1558,24 +1678,26 @@ static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root)
&ptr_root_lib);
bool prop_exists = RNA_path_resolve_property(&ptr_root, op->rna_path, &ptr, &prop);
- BLI_assert(prop_exists);
- prop_exists = RNA_path_resolve_property(&ptr_root_lib, op->rna_path, &ptr_lib, &prop_lib);
-
if (prop_exists) {
- BLI_assert(ELEM(RNA_property_type(prop), PROP_POINTER, PROP_COLLECTION));
- BLI_assert(RNA_property_type(prop) == RNA_property_type(prop_lib));
- if (is_collection) {
- ptr.type = RNA_property_pointer_type(&ptr, prop);
- ptr_lib.type = RNA_property_pointer_type(&ptr_lib, prop_lib);
- }
- else {
- ptr = RNA_property_pointer_get(&ptr, prop);
- ptr_lib = RNA_property_pointer_get(&ptr_lib, prop_lib);
- }
- if (ptr.owner_id != NULL && ptr_lib.owner_id != NULL) {
- BLI_assert(ptr.type == ptr_lib.type);
- do_op_delete = !(RNA_struct_is_ID(ptr.type) && ptr.owner_id->override_library != NULL &&
- ptr.owner_id->override_library->reference == ptr_lib.owner_id);
+ prop_exists = RNA_path_resolve_property(&ptr_root_lib, op->rna_path, &ptr_lib, &prop_lib);
+
+ if (prop_exists) {
+ BLI_assert(ELEM(RNA_property_type(prop), PROP_POINTER, PROP_COLLECTION));
+ BLI_assert(RNA_property_type(prop) == RNA_property_type(prop_lib));
+ if (is_collection) {
+ ptr.type = RNA_property_pointer_type(&ptr, prop);
+ ptr_lib.type = RNA_property_pointer_type(&ptr_lib, prop_lib);
+ }
+ else {
+ ptr = RNA_property_pointer_get(&ptr, prop);
+ ptr_lib = RNA_property_pointer_get(&ptr_lib, prop_lib);
+ }
+ if (ptr.owner_id != NULL && ptr_lib.owner_id != NULL) {
+ BLI_assert(ptr.type == ptr_lib.type);
+ do_op_delete = !(RNA_struct_is_ID(ptr.type) &&
+ ptr.owner_id->override_library != NULL &&
+ ptr.owner_id->override_library->reference == ptr_lib.owner_id);
+ }
}
}
}
@@ -1619,31 +1741,37 @@ static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *i
return;
}
- void **entry_pp = BLI_ghash_lookup(bmain->relations->id_user_to_used, id_root);
- if (entry_pp == NULL) {
- /* Already processed. */
+ void **entry_vp = BLI_ghash_lookup_p(bmain->relations->relations_from_pointers, id_root);
+ if (entry_vp == NULL) {
+ /* This ID is not used by nor using any other ID. */
+ lib_override_library_id_reset_do(bmain, id_root);
+ return;
+ }
+
+ MainIDRelationsEntry *entry = *entry_vp;
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
+ /* This ID has already been processed. */
return;
}
lib_override_library_id_reset_do(bmain, id_root);
/* This way we won't process again that ID, should we encounter it again through another
- * relationship hierarchy.
- * Note that this does not free any memory from relations, so we can still use the entries.
- */
- BKE_main_relations_ID_remove(bmain, id_root);
+ * relationship hierarchy. */
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
- for (MainIDRelationsEntry *entry = *entry_pp; entry != NULL; entry = entry->next) {
- if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
+ for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
+ to_id_entry = to_id_entry->next) {
+ if ((to_id_entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
/* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
* actual dependencies. */
continue;
}
/* We only consider IDs from the same library. */
- if (entry->id_pointer != NULL) {
- ID *id_entry = *entry->id_pointer;
- if (id_entry->override_library != NULL) {
- lib_override_library_id_hierarchy_recursive_reset(bmain, id_entry);
+ if (*to_id_entry->id_pointer.to != NULL) {
+ ID *to_id = *to_id_entry->id_pointer.to;
+ if (to_id->override_library != NULL) {
+ lib_override_library_id_hierarchy_recursive_reset(bmain, to_id);
}
}
}
@@ -1922,7 +2050,9 @@ ID *BKE_lib_override_library_operations_store_start(Main *bmain,
ID *local)
{
if (ID_IS_OVERRIDE_LIBRARY_TEMPLATE(local) || ID_IS_OVERRIDE_LIBRARY_VIRTUAL(local)) {
- /* This is actually purely local data with an override template, nothing to do here! */
+ /* This is actually purely local data with an override template, or one of those embedded IDs
+ * (root node trees, master collections or shapekeys) that cannot have their own override.
+ * Nothing to do here! */
return NULL;
}
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index e687e94073d..1fd51544ba7 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -237,9 +237,12 @@ static void library_foreach_ID_link(Main *bmain,
* but we might as well use it (Main->relations is always assumed valid,
* it's responsibility of code creating it to free it,
* especially if/when it starts modifying Main database). */
- MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
- for (; entry != NULL; entry = entry->next) {
- BKE_lib_query_foreachid_process(&data, entry->id_pointer, entry->usage_flag);
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers,
+ id);
+ for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
+ to_id_entry = to_id_entry->next) {
+ BKE_lib_query_foreachid_process(
+ &data, to_id_entry->id_pointer.to, to_id_entry->usage_flag);
}
continue;
}
@@ -413,13 +416,14 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
return ELEM(id_type_used, ID_MA);
case ID_SIM:
return ELEM(id_type_used, ID_OB, ID_IM);
+ case ID_WM:
+ return ELEM(id_type_used, ID_SCE, ID_WS);
case ID_IM:
case ID_VF:
case ID_TXT:
case ID_SO:
case ID_AR:
case ID_AC:
- case ID_WM:
case ID_PAL:
case ID_PC:
case ID_CF:
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 6a560d51362..d2f1196d804 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -84,6 +84,8 @@ IDTypeInfo IDType_ID_LI = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath)
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index a47a0c043ff..4a2afb7f5e6 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -209,6 +209,8 @@ IDTypeInfo IDType_ID_LA = {
.blend_read_expand = light_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
Light *BKE_light_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/lightprobe.c b/source/blender/blenkernel/intern/lightprobe.c
index 0553c070fdf..4ef3b8c3237 100644
--- a/source/blender/blenkernel/intern/lightprobe.c
+++ b/source/blender/blenkernel/intern/lightprobe.c
@@ -107,6 +107,8 @@ IDTypeInfo IDType_ID_LP = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
void BKE_lightprobe_type_set(LightProbe *probe, const short lightprobe_type)
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 8542959d4b0..283e2a94732 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -767,6 +767,8 @@ IDTypeInfo IDType_ID_LS = {
.blend_read_expand = linestyle_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
static const char *modifier_name[LS_MODIFIER_NUM] = {
diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c
index 4b577ccec2c..6f94b3355fa 100644
--- a/source/blender/blenkernel/intern/main.c
+++ b/source/blender/blenkernel/intern/main.c
@@ -211,35 +211,51 @@ void BKE_main_unlock(struct Main *bmain)
static int main_relations_create_idlink_cb(LibraryIDLinkCallbackData *cb_data)
{
- MainIDRelations *rel = cb_data->user_data;
+ MainIDRelations *bmain_relations = cb_data->user_data;
ID *id_self = cb_data->id_self;
ID **id_pointer = cb_data->id_pointer;
const int cb_flag = cb_data->cb_flag;
if (*id_pointer) {
- MainIDRelationsEntry *entry, **entry_p;
-
- entry = BLI_mempool_alloc(rel->entry_pool);
- if (BLI_ghash_ensure_p(rel->id_user_to_used, id_self, (void ***)&entry_p)) {
- entry->next = *entry_p;
- }
- else {
- entry->next = NULL;
+ MainIDRelationsEntry **entry_p;
+
+ /* Add `id_pointer` as child of `id_self`. */
+ {
+ if (!BLI_ghash_ensure_p(
+ bmain_relations->relations_from_pointers, id_self, (void ***)&entry_p)) {
+ *entry_p = MEM_callocN(sizeof(**entry_p), __func__);
+ (*entry_p)->session_uuid = id_self->session_uuid;
+ }
+ else {
+ BLI_assert((*entry_p)->session_uuid == id_self->session_uuid);
+ }
+ MainIDRelationsEntryItem *to_id_entry = BLI_mempool_alloc(bmain_relations->entry_items_pool);
+ to_id_entry->next = (*entry_p)->to_ids;
+ to_id_entry->id_pointer.to = id_pointer;
+ to_id_entry->session_uuid = (*id_pointer != NULL) ? (*id_pointer)->session_uuid :
+ MAIN_ID_SESSION_UUID_UNSET;
+ to_id_entry->usage_flag = cb_flag;
+ (*entry_p)->to_ids = to_id_entry;
}
- entry->id_pointer = id_pointer;
- entry->usage_flag = cb_flag;
- *entry_p = entry;
- entry = BLI_mempool_alloc(rel->entry_pool);
- if (BLI_ghash_ensure_p(rel->id_used_to_user, *id_pointer, (void ***)&entry_p)) {
- entry->next = *entry_p;
- }
- else {
- entry->next = NULL;
+ /* Add `id_self` as parent of `id_pointer`. */
+ if (*id_pointer != NULL) {
+ if (!BLI_ghash_ensure_p(
+ bmain_relations->relations_from_pointers, *id_pointer, (void ***)&entry_p)) {
+ *entry_p = MEM_callocN(sizeof(**entry_p), __func__);
+ (*entry_p)->session_uuid = (*id_pointer)->session_uuid;
+ }
+ else {
+ BLI_assert((*entry_p)->session_uuid == (*id_pointer)->session_uuid);
+ }
+ MainIDRelationsEntryItem *from_id_entry = BLI_mempool_alloc(
+ bmain_relations->entry_items_pool);
+ from_id_entry->next = (*entry_p)->from_ids;
+ from_id_entry->id_pointer.from = id_self;
+ from_id_entry->session_uuid = id_self->session_uuid;
+ from_id_entry->usage_flag = cb_flag;
+ (*entry_p)->from_ids = from_id_entry;
}
- entry->id_pointer = (ID **)id_self;
- entry->usage_flag = cb_flag;
- *entry_p = entry;
}
return IDWALK_RET_NOP;
@@ -253,61 +269,68 @@ void BKE_main_relations_create(Main *bmain, const short flag)
}
bmain->relations = MEM_mallocN(sizeof(*bmain->relations), __func__);
- bmain->relations->id_used_to_user = BLI_ghash_new(
+ bmain->relations->relations_from_pointers = BLI_ghash_new(
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
- bmain->relations->id_user_to_used = BLI_ghash_new(
- BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
- bmain->relations->entry_pool = BLI_mempool_create(
- sizeof(MainIDRelationsEntry), 128, 128, BLI_MEMPOOL_NOP);
+ bmain->relations->entry_items_pool = BLI_mempool_create(
+ sizeof(MainIDRelationsEntryItem), 128, 128, BLI_MEMPOOL_NOP);
+
+ bmain->relations->flag = flag;
ID *id;
FOREACH_MAIN_ID_BEGIN (bmain, id) {
const int idwalk_flag = IDWALK_READONLY |
((flag & MAINIDRELATIONS_INCLUDE_UI) != 0 ? IDWALK_INCLUDE_UI : 0);
+
+ /* Ensure all IDs do have an entry, even if they are not connected to any other. */
+ MainIDRelationsEntry **entry_p;
+ if (!BLI_ghash_ensure_p(bmain->relations->relations_from_pointers, id, (void ***)&entry_p)) {
+ *entry_p = MEM_callocN(sizeof(**entry_p), __func__);
+ (*entry_p)->session_uuid = id->session_uuid;
+ }
+ else {
+ BLI_assert((*entry_p)->session_uuid == id->session_uuid);
+ }
+
BKE_library_foreach_ID_link(
NULL, id, main_relations_create_idlink_cb, bmain->relations, idwalk_flag);
}
FOREACH_MAIN_ID_END;
-
- bmain->relations->flag = flag;
}
void BKE_main_relations_free(Main *bmain)
{
- if (bmain->relations) {
- if (bmain->relations->id_used_to_user) {
- BLI_ghash_free(bmain->relations->id_used_to_user, NULL, NULL);
- }
- if (bmain->relations->id_user_to_used) {
- BLI_ghash_free(bmain->relations->id_user_to_used, NULL, NULL);
+ if (bmain->relations != NULL) {
+ if (bmain->relations->relations_from_pointers != NULL) {
+ BLI_ghash_free(bmain->relations->relations_from_pointers, NULL, MEM_freeN);
}
- BLI_mempool_destroy(bmain->relations->entry_pool);
+ BLI_mempool_destroy(bmain->relations->entry_items_pool);
MEM_freeN(bmain->relations);
bmain->relations = NULL;
}
}
-/**
- * Remove an ID from the relations (the two entries for that ID, not the ID from entries in other
- * IDs' relationships).
- *
- * Does not free any allocated memory.
- * Allows to use those relations as a way to mark an ID as already processed, without requiring any
- * additional tagging or GSet.
- * Obviously, relations should be freed after use then, since this will make them fully invalid.
- */
-void BKE_main_relations_ID_remove(Main *bmain, ID *id)
+/** Set or clear given `tag` in all relation entries of given `bmain`. */
+void BKE_main_relations_tag_set(struct Main *bmain,
+ const MainIDRelationsEntryTags tag,
+ const bool value)
{
- if (bmain->relations) {
- /* Note: we do not free the entries from the mempool, those will be dealt with when finally
- * freeing the whole relations. */
- if (bmain->relations->id_used_to_user) {
- BLI_ghash_remove(bmain->relations->id_used_to_user, id, NULL, NULL);
+ if (bmain->relations == NULL) {
+ return;
+ }
+
+ GHashIterator *gh_iter;
+ for (gh_iter = BLI_ghashIterator_new(bmain->relations->relations_from_pointers);
+ !BLI_ghashIterator_done(gh_iter);
+ BLI_ghashIterator_step(gh_iter)) {
+ MainIDRelationsEntry *entry = BLI_ghashIterator_getValue(gh_iter);
+ if (value) {
+ entry->tags |= tag;
}
- if (bmain->relations->id_user_to_used) {
- BLI_ghash_remove(bmain->relations->id_user_to_used, id, NULL, NULL);
+ else {
+ entry->tags &= ~tag;
}
}
+ BLI_ghashIterator_free(gh_iter);
}
/**
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 04fec1e57c4..83d9449934c 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -270,6 +270,8 @@ IDTypeInfo IDType_ID_MSK = {
.blend_read_expand = mask_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
static struct {
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
index 595fd0c9550..69f60ca0384 100644
--- a/source/blender/blenkernel/intern/mask_evaluate.c
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -128,8 +128,8 @@ int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const uns
}
float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
- unsigned int *tot_diff_point,
- const unsigned int resol))[2]
+ const unsigned int resol,
+ unsigned int *r_tot_diff_point))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
@@ -140,12 +140,12 @@ float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
if (spline->tot_point <= 1) {
/* nothing to differentiate */
- *tot_diff_point = 0;
+ *r_tot_diff_point = 0;
return NULL;
}
/* len+1 because of 'forward_diff_bezier' function */
- *tot_diff_point = tot;
+ *r_tot_diff_point = tot;
diff_points = fp = MEM_mallocN((tot + 1) * sizeof(*diff_points), "mask spline vets");
a = spline->tot_point - 1;
@@ -192,11 +192,11 @@ float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
}
float (*BKE_mask_spline_differentiate(
- MaskSpline *spline, int width, int height, unsigned int *tot_diff_point))[2]
+ MaskSpline *spline, int width, int height, unsigned int *r_tot_diff_point))[2]
{
uint resol = BKE_mask_spline_resolution(spline, width, height);
- return BKE_mask_spline_differentiate_with_resolution(spline, tot_diff_point, resol);
+ return BKE_mask_spline_differentiate_with_resolution(spline, resol, r_tot_diff_point);
}
/* ** feather points self-intersection collapse routine ** */
@@ -507,9 +507,9 @@ 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,
- unsigned int *tot_feather_point,
const unsigned int resol,
- const bool do_feather_isect))[2]
+ const bool do_feather_isect,
+ unsigned int *r_tot_feather_point))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
MaskSplinePoint *point_curr, *point_prev;
@@ -569,7 +569,7 @@ static float (*mask_spline_feather_differentiated_points_with_resolution__even(
point_curr++;
}
- *tot_feather_point = tot;
+ *r_tot_feather_point = tot;
if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
@@ -581,9 +581,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,
- unsigned int *tot_feather_point,
const unsigned int resol,
- const bool do_feather_isect))[2]
+ const bool do_feather_isect,
+ unsigned int *r_tot_feather_point))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
@@ -594,12 +594,12 @@ static float (*mask_spline_feather_differentiated_points_with_resolution__double
if (spline->tot_point <= 1) {
/* nothing to differentiate */
- *tot_feather_point = 0;
+ *r_tot_feather_point = 0;
return NULL;
}
/* len+1 because of 'forward_diff_bezier' function */
- *tot_feather_point = tot;
+ *r_tot_feather_point = tot;
feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline vets");
a = spline->tot_point - 1;
@@ -665,7 +665,7 @@ static float (*mask_spline_feather_differentiated_points_with_resolution__double
len_feather = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]);
- /* scale by chane in length */
+ /* scale by change in length */
len_scalar = len_feather / len_base;
dist_ensure_v2_v2fl(bezt_prev->vec[2],
bezt_prev->vec[1],
@@ -724,24 +724,24 @@ static float (*mask_spline_feather_differentiated_points_with_resolution__double
* values align with #BKE_mask_spline_differentiate_with_resolution
* when \a resol arguments match.
*/
-float (
- *BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline,
- unsigned int *tot_feather_point,
- const unsigned int resol,
- const bool do_feather_isect))[2]
+float (*BKE_mask_spline_feather_differentiated_points_with_resolution(
+ MaskSpline *spline,
+ const unsigned int resol,
+ const bool do_feather_isect,
+ unsigned int *r_tot_feather_point))[2]
{
switch (spline->offset_mode) {
case MASK_SPLINE_OFFSET_EVEN:
return mask_spline_feather_differentiated_points_with_resolution__even(
- spline, tot_feather_point, resol, do_feather_isect);
+ spline, resol, do_feather_isect, r_tot_feather_point);
case MASK_SPLINE_OFFSET_SMOOTH:
default:
return mask_spline_feather_differentiated_points_with_resolution__double(
- spline, tot_feather_point, resol, do_feather_isect);
+ spline, resol, do_feather_isect, r_tot_feather_point);
}
}
-float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2]
+float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *r_tot_feather_point))[2]
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
@@ -783,7 +783,7 @@ float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_poin
}
}
- *tot_feather_point = tot;
+ *r_tot_feather_point = tot;
return feather;
}
@@ -793,7 +793,7 @@ float *BKE_mask_point_segment_feather_diff(MaskSpline *spline,
MaskSplinePoint *point,
int width,
int height,
- unsigned int *tot_feather_point)
+ unsigned int *r_tot_feather_point)
{
float *feather, *fp;
unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
@@ -812,7 +812,7 @@ float *BKE_mask_point_segment_feather_diff(MaskSpline *spline,
fp[1] = co[1] + n[1] * weight;
}
- *tot_feather_point = resol;
+ *r_tot_feather_point = resol;
return feather;
}
@@ -821,7 +821,7 @@ float *BKE_mask_point_segment_diff(MaskSpline *spline,
MaskSplinePoint *point,
int width,
int height,
- unsigned int *tot_diff_point)
+ unsigned int *r_tot_diff_point)
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
@@ -837,7 +837,7 @@ float *BKE_mask_point_segment_diff(MaskSpline *spline,
}
/* resol+1 because of 'forward_diff_bezier' function */
- *tot_diff_point = resol + 1;
+ *r_tot_diff_point = resol + 1;
diff_points = fp = MEM_callocN(sizeof(float[2]) * (resol + 1), "mask segment vets");
for (j = 0; j < 2; j++) {
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 583ee8f2857..d29a6e75954 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -646,11 +646,11 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
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);
- diff_points = BKE_mask_spline_differentiate_with_resolution(spline, &tot_diff_point, resol);
+ diff_points = BKE_mask_spline_differentiate_with_resolution(spline, resol, &tot_diff_point);
if (do_feather) {
diff_feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(
- spline, &tot_diff_feather_points, resol, false);
+ spline, resol, false, &tot_diff_feather_points);
BLI_assert(diff_feather_points);
}
else {
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index e892a3f4d53..70906065347 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -274,6 +274,8 @@ IDTypeInfo IDType_ID_MA = {
.blend_read_expand = material_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
void BKE_gpencil_material_attr_init(Material *ma)
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 65ec91c57cf..849c7ef57fb 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -204,6 +204,8 @@ IDTypeInfo IDType_ID_MB = {
.blend_read_expand = metaball_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* Functions */
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index 051c7e56ef9..1550401cc9c 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -263,7 +263,7 @@ static void build_bvh_spatial(PROCESS *process,
* BASED AT CODE (but mostly rewritten) :
* C code from the article
* "An Implicit Surface Polygonizer"
- * by Jules Bloomenthal, jbloom@beauty.gmu.edu
+ * by Jules Bloomenthal <jbloom@beauty.gmu.edu>
* in "Graphics Gems IV", Academic Press, 1994
*
* Authored by Jules Bloomenthal, Xerox PARC.
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 950885d2114..c15484f8e72 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -364,6 +364,8 @@ IDTypeInfo IDType_ID_ME = {
.blend_read_expand = mesh_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
enum {
@@ -939,7 +941,7 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
Mesh *me_dst = BKE_id_new_nomain(ID_ME, NULL);
- me_dst->mselect = MEM_dupallocN(me_dst->mselect);
+ me_dst->mselect = MEM_dupallocN(me_src->mselect);
me_dst->totvert = verts_len;
me_dst->totedge = edges_len;
@@ -1217,7 +1219,7 @@ int test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr)
}
/* Check corrupt cases, bow-tie geometry,
- * cant handle these because edge data wont exist so just return 0. */
+ * can't handle these because edge data won't exist so just return 0. */
if (nr == 3) {
if (
/* real edges */
diff --git a/source/blender/blenkernel/intern/mesh_fair.cc b/source/blender/blenkernel/intern/mesh_fair.cc
index 75dd396d10a..ac6dd96ed90 100644
--- a/source/blender/blenkernel/intern/mesh_fair.cc
+++ b/source/blender/blenkernel/intern/mesh_fair.cc
@@ -475,7 +475,7 @@ static void prefair_and_fair_vertices(FairingContext *fairing_context,
/* Fair. */
VoronoiVertexWeight *voronoi_vertex_weights = new VoronoiVertexWeight(fairing_context);
- /* TODO: Implemente cotangent loop weights. */
+ /* TODO: Implement cotangent loop weights. */
fairing_context->fair_vertices(
affected_vertices, depth, voronoi_vertex_weights, uniform_loop_weights);
diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc
index 0aaca33124a..0b0aeb50d37 100644
--- a/source/blender/blenkernel/intern/mesh_validate.cc
+++ b/source/blender/blenkernel/intern/mesh_validate.cc
@@ -263,6 +263,6 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
mesh->totedge = new_totedge;
mesh->medge = new_edges.data();
- /* Explicitely clear edge maps, because that way it can be parallelized. */
+ /* Explicitly clear edge maps, because that way it can be parallelized. */
clear_hash_tables(edge_maps);
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index e82ed62ed5b..c1ebd06465b 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -362,6 +362,8 @@ IDTypeInfo IDType_ID_MC = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/*********************** movieclip buffer loaders *************************/
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 441da8b134a..45ac20ef154 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -781,7 +781,7 @@ static DerivedMesh *subsurf_dm_create_local(Scene *scene,
smd.levels = smd.renderLevels = lvl;
smd.quality = 3;
if (!is_plain_uv) {
- smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
+ smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES;
}
else {
smd.uv_smooth = SUBSURF_UV_SMOOTH_NONE;
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c
index e3d670f7c39..02b9bb852d6 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.c
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.c
@@ -201,8 +201,8 @@ static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex
/* Repeat a similar operation for all vertices in the queue. */
/* In this case, add to the queue the vertices connected by 2 steps using the diagonals in any
- * direction. If a solution exists and intial_vertex was a pole, this is guaranteed that will tag
- * all the (0,0) vertices of the grids, and nothing else. */
+ * direction. If a solution exists and `initial_vertex` was a pole, this is guaranteed that will
+ * tag all the (0,0) vertices of the grids, and nothing else. */
/* If it was not a pole, it may or may not find a solution, even if the solution exists. */
while (!BLI_gsqueue_is_empty(queue)) {
BMVert *from_v;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.cc
index 76885eadaae..e34afd1ce17 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.cc
@@ -25,10 +25,10 @@
#include "MEM_guardedalloc.h"
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
+#include <climits>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
/* Allow using deprecated functionality for .blend file I/O. */
#define DNA_DEPRECATED_ALLOW
@@ -109,7 +109,7 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree),
static void ntree_init_data(ID *id)
{
bNodeTree *ntree = (bNodeTree *)id;
- ntree_set_typeinfo(ntree, NULL);
+ ntree_set_typeinfo(ntree, nullptr);
}
static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
@@ -121,7 +121,7 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
/* in case a running nodetree is copied */
- ntree_dst->execdata = NULL;
+ ntree_dst->execdata = nullptr;
BLI_listbase_clear(&ntree_dst->nodes);
BLI_listbase_clear(&ntree_dst->links);
@@ -133,17 +133,17 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
bNode *new_node = BKE_node_copy_ex(ntree_dst, node_src, flag_subdata, true);
BLI_ghash_insert(new_pointers, (void *)node_src, new_node);
/* Store mapping to inputs. */
- bNodeSocket *new_input_sock = new_node->inputs.first;
- const bNodeSocket *input_sock_src = node_src->inputs.first;
- while (new_input_sock != NULL) {
+ bNodeSocket *new_input_sock = (bNodeSocket *)new_node->inputs.first;
+ const bNodeSocket *input_sock_src = (const bNodeSocket *)node_src->inputs.first;
+ while (new_input_sock != nullptr) {
BLI_ghash_insert(new_pointers, (void *)input_sock_src, new_input_sock);
new_input_sock = new_input_sock->next;
input_sock_src = input_sock_src->next;
}
/* Store mapping to outputs. */
- bNodeSocket *new_output_sock = new_node->outputs.first;
- const bNodeSocket *output_sock_src = node_src->outputs.first;
- while (new_output_sock != NULL) {
+ bNodeSocket *new_output_sock = (bNodeSocket *)new_node->outputs.first;
+ const bNodeSocket *output_sock_src = (const bNodeSocket *)node_src->outputs.first;
+ while (new_output_sock != nullptr) {
BLI_ghash_insert(new_pointers, (void *)output_sock_src, new_output_sock);
new_output_sock = new_output_sock->next;
output_sock_src = output_sock_src->next;
@@ -153,10 +153,13 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
/* copy links */
BLI_duplicatelist(&ntree_dst->links, &ntree_src->links);
LISTBASE_FOREACH (bNodeLink *, link_dst, &ntree_dst->links) {
- link_dst->fromnode = BLI_ghash_lookup_default(new_pointers, link_dst->fromnode, NULL);
- link_dst->fromsock = BLI_ghash_lookup_default(new_pointers, link_dst->fromsock, NULL);
- link_dst->tonode = BLI_ghash_lookup_default(new_pointers, link_dst->tonode, NULL);
- link_dst->tosock = BLI_ghash_lookup_default(new_pointers, link_dst->tosock, NULL);
+ link_dst->fromnode = (bNode *)BLI_ghash_lookup_default(
+ new_pointers, link_dst->fromnode, nullptr);
+ link_dst->fromsock = (bNodeSocket *)BLI_ghash_lookup_default(
+ new_pointers, link_dst->fromsock, nullptr);
+ link_dst->tonode = (bNode *)BLI_ghash_lookup_default(new_pointers, link_dst->tonode, nullptr);
+ link_dst->tosock = (bNodeSocket *)BLI_ghash_lookup_default(
+ new_pointers, link_dst->tosock, nullptr);
/* update the link socket's pointer */
if (link_dst->tosock) {
link_dst->tosock->link = link_dst;
@@ -166,14 +169,18 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
/* copy interface sockets */
BLI_duplicatelist(&ntree_dst->inputs, &ntree_src->inputs);
bNodeSocket *sock_dst, *sock_src;
- for (sock_dst = ntree_dst->inputs.first, sock_src = ntree_src->inputs.first; sock_dst != NULL;
- sock_dst = sock_dst->next, sock_src = sock_src->next) {
+ for (sock_dst = (bNodeSocket *)ntree_dst->inputs.first,
+ sock_src = (bNodeSocket *)ntree_src->inputs.first;
+ sock_dst != nullptr;
+ sock_dst = (bNodeSocket *)sock_dst->next, sock_src = (bNodeSocket *)sock_src->next) {
node_socket_copy(sock_dst, sock_src, flag_subdata);
}
BLI_duplicatelist(&ntree_dst->outputs, &ntree_src->outputs);
- for (sock_dst = ntree_dst->outputs.first, sock_src = ntree_src->outputs.first; sock_dst != NULL;
- sock_dst = sock_dst->next, sock_src = sock_src->next) {
+ for (sock_dst = (bNodeSocket *)ntree_dst->outputs.first,
+ sock_src = (bNodeSocket *)ntree_src->outputs.first;
+ sock_dst != nullptr;
+ sock_dst = (bNodeSocket *)sock_dst->next, sock_src = (bNodeSocket *)sock_src->next) {
node_socket_copy(sock_dst, sock_src, flag_subdata);
}
@@ -185,26 +192,29 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
NODE_INSTANCE_HASH_ITER (iter, ntree_src->previews) {
bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
- bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
+ bNodePreview *preview = (bNodePreview *)BKE_node_instance_hash_iterator_get_value(&iter);
BKE_node_instance_hash_insert(ntree_dst->previews, key, BKE_node_preview_copy(preview));
}
}
else {
- ntree_dst->previews = NULL;
+ ntree_dst->previews = nullptr;
}
/* update node->parent pointers */
- for (bNode *node_dst = ntree_dst->nodes.first, *node_src = ntree_src->nodes.first; node_dst;
- node_dst = node_dst->next, node_src = node_src->next) {
+ for (bNode *node_dst = (bNode *)ntree_dst->nodes.first,
+ *node_src = (bNode *)ntree_src->nodes.first;
+ node_dst;
+ node_dst = (bNode *)node_dst->next, node_src = (bNode *)node_src->next) {
if (node_dst->parent) {
- node_dst->parent = BLI_ghash_lookup_default(new_pointers, node_dst->parent, NULL);
+ node_dst->parent = (bNode *)BLI_ghash_lookup_default(
+ new_pointers, node_dst->parent, nullptr);
}
}
- BLI_ghash_free(new_pointers, NULL, NULL);
+ BLI_ghash_free(new_pointers, nullptr, nullptr);
/* node tree will generate its own interface type */
- ntree_dst->interface_type = NULL;
+ ntree_dst->interface_type = nullptr;
}
static void ntree_free_data(ID *id)
@@ -223,7 +233,7 @@ static void ntree_free_data(ID *id)
break;
case NTREE_TEXTURE:
ntreeTexEndExecTree(ntree->execdata);
- ntree->execdata = NULL;
+ ntree->execdata = nullptr;
break;
}
}
@@ -267,17 +277,18 @@ static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
- bNodeSocketValueObject *default_value = sock->default_value;
+ bNodeSocketValueObject *default_value = (bNodeSocketValueObject *)sock->default_value;
BKE_LIB_FOREACHID_PROCESS(data, default_value->value, IDWALK_CB_USER);
break;
}
case SOCK_IMAGE: {
- bNodeSocketValueImage *default_value = sock->default_value;
+ bNodeSocketValueImage *default_value = (bNodeSocketValueImage *)sock->default_value;
BKE_LIB_FOREACHID_PROCESS(data, default_value->value, IDWALK_CB_USER);
break;
}
case SOCK_COLLECTION: {
- bNodeSocketValueCollection *default_value = sock->default_value;
+ bNodeSocketValueCollection *default_value = (bNodeSocketValueCollection *)
+ sock->default_value;
BKE_LIB_FOREACHID_PROCESS(data, default_value->value, IDWALK_CB_USER);
break;
}
@@ -327,11 +338,10 @@ static void node_foreach_cache(ID *id,
void *user_data)
{
bNodeTree *nodetree = (bNodeTree *)id;
- IDCacheKey key = {
- .id_session_uuid = id->session_uuid,
- .offset_in_ID = offsetof(bNodeTree, previews),
- .cache_v = nodetree->previews,
- };
+ IDCacheKey key = {0};
+ key.id_session_uuid = id->session_uuid;
+ key.offset_in_ID = offsetof(bNodeTree, previews);
+ key.cache_v = nodetree->previews;
/* TODO, see also `direct_link_nodetree()` in readfile.c. */
#if 0
@@ -351,7 +361,7 @@ static void node_foreach_cache(ID *id,
static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *sock)
{
- if (sock->default_value == NULL) {
+ if (sock->default_value == nullptr) {
return;
}
@@ -448,7 +458,7 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
/* could be handlerized at some point, now only 1 exception still */
if ((ntree->type == NTREE_SHADER) &&
ELEM(node->type, SH_NODE_CURVE_VEC, SH_NODE_CURVE_RGB)) {
- BKE_curvemapping_blend_write(writer, node->storage);
+ BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
}
else if (ntree->type == NTREE_SHADER && (node->type == SH_NODE_SCRIPT)) {
NodeShaderScript *nss = (NodeShaderScript *)node->storage;
@@ -462,11 +472,11 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
CMP_NODE_CURVE_VEC,
CMP_NODE_CURVE_RGB,
CMP_NODE_HUECORRECT)) {
- BKE_curvemapping_blend_write(writer, node->storage);
+ BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
}
else if ((ntree->type == NTREE_TEXTURE) &&
(node->type == TEX_NODE_CURVE_RGB || node->type == TEX_NODE_CURVE_TIME)) {
- BKE_curvemapping_blend_write(writer, node->storage);
+ BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
}
else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_MOVIEDISTORTION)) {
/* pass */
@@ -474,7 +484,7 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_GLARE)) {
/* Simple forward compatibility for fix for T50736.
* Not ideal (there is no ideal solution here), but should do for now. */
- NodeGlare *ndg = node->storage;
+ NodeGlare *ndg = (NodeGlare *)node->storage;
/* Not in undo case. */
if (!BLO_write_is_undo(writer)) {
switch (ndg->type) {
@@ -543,10 +553,10 @@ static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_addres
/* Clean up, important in undo case to reduce false detection of changed datablocks. */
ntree->init = 0; /* to set callbacks and force setting types */
ntree->is_updating = false;
- ntree->typeinfo = NULL;
- ntree->interface_type = NULL;
- ntree->progress = NULL;
- ntree->execdata = NULL;
+ ntree->typeinfo = nullptr;
+ ntree->interface_type = nullptr;
+ ntree->progress = nullptr;
+ ntree->execdata = nullptr;
BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id);
@@ -560,10 +570,11 @@ static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
IDP_BlendDataRead(reader, &sock->prop);
BLO_read_data_address(reader, &sock->link);
- sock->typeinfo = NULL;
+ sock->typeinfo = nullptr;
BLO_read_data_address(reader, &sock->storage);
BLO_read_data_address(reader, &sock->default_value);
- sock->cache = NULL;
+ sock->total_inputs = 0; /* Clear runtime data set before drawing. */
+ sock->cache = nullptr;
}
/* ntree itself has been read! */
@@ -572,18 +583,18 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
/* note: writing and reading goes in sync, for speed */
ntree->init = 0; /* to set callbacks and force setting types */
ntree->is_updating = false;
- ntree->typeinfo = NULL;
- ntree->interface_type = NULL;
+ ntree->typeinfo = nullptr;
+ ntree->interface_type = nullptr;
- ntree->progress = NULL;
- ntree->execdata = NULL;
+ ntree->progress = nullptr;
+ ntree->execdata = nullptr;
BLO_read_data_address(reader, &ntree->adt);
BKE_animdata_blend_read_data(reader, ntree->adt);
BLO_read_list(reader, &ntree->nodes);
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- node->typeinfo = NULL;
+ node->typeinfo = nullptr;
BLO_read_list(reader, &node->inputs);
BLO_read_list(reader, &node->outputs);
@@ -618,7 +629,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
case CMP_NODE_HUECORRECT:
case TEX_NODE_CURVE_RGB:
case TEX_NODE_CURVE_TIME: {
- BKE_curvemapping_blend_read(reader, node->storage);
+ BKE_curvemapping_blend_read(reader, (CurveMapping *)node->storage);
break;
}
case SH_NODE_SCRIPT: {
@@ -634,22 +645,22 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
case SH_NODE_TEX_IMAGE: {
NodeTexImage *tex = (NodeTexImage *)node->storage;
tex->iuser.ok = 1;
- tex->iuser.scene = NULL;
+ tex->iuser.scene = nullptr;
break;
}
case SH_NODE_TEX_ENVIRONMENT: {
NodeTexEnvironment *tex = (NodeTexEnvironment *)node->storage;
tex->iuser.ok = 1;
- tex->iuser.scene = NULL;
+ tex->iuser.scene = nullptr;
break;
}
case CMP_NODE_IMAGE:
case CMP_NODE_R_LAYERS:
case CMP_NODE_VIEWER:
case CMP_NODE_SPLITVIEWER: {
- ImageUser *iuser = node->storage;
+ ImageUser *iuser = (ImageUser *)node->storage;
iuser->ok = 1;
- iuser->scene = NULL;
+ iuser->scene = nullptr;
break;
}
case CMP_NODE_CRYPTOMATTE: {
@@ -659,9 +670,9 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
break;
}
case TEX_NODE_IMAGE: {
- ImageUser *iuser = node->storage;
+ ImageUser *iuser = (ImageUser *)node->storage;
iuser->ok = 1;
- iuser->scene = NULL;
+ iuser->scene = nullptr;
break;
}
default:
@@ -701,7 +712,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
}
/* TODO, should be dealt by new generic cache handling of IDs... */
- ntree->previews = NULL;
+ ntree->previews = nullptr;
/* type verification is in lib-link */
}
@@ -718,17 +729,18 @@ static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSock
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
- bNodeSocketValueObject *default_value = sock->default_value;
+ bNodeSocketValueObject *default_value = (bNodeSocketValueObject *)sock->default_value;
BLO_read_id_address(reader, lib, &default_value->value);
break;
}
case SOCK_IMAGE: {
- bNodeSocketValueImage *default_value = sock->default_value;
+ bNodeSocketValueImage *default_value = (bNodeSocketValueImage *)sock->default_value;
BLO_read_id_address(reader, lib, &default_value->value);
break;
}
case SOCK_COLLECTION: {
- bNodeSocketValueImage *default_value = sock->default_value;
+ bNodeSocketValueCollection *default_value = (bNodeSocketValueCollection *)
+ sock->default_value;
BLO_read_id_address(reader, lib, &default_value->value);
break;
}
@@ -777,7 +789,7 @@ void ntreeBlendReadLib(struct BlendLibReader *reader, struct bNodeTree *ntree)
* first versioning that can change types still without functions that
* update the typeinfo pointers. Versioning after lib linking needs
* these top be valid. */
- ntreeSetTypes(NULL, ntree);
+ ntreeSetTypes(nullptr, ntree);
/* For nodes with static socket layout, add/remove sockets as needed
* to match the static layout. */
@@ -798,21 +810,22 @@ static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
{
IDP_BlendReadExpand(expander, sock->prop);
- if (sock->default_value != NULL) {
+ if (sock->default_value != nullptr) {
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
- bNodeSocketValueObject *default_value = sock->default_value;
+ bNodeSocketValueObject *default_value = (bNodeSocketValueObject *)sock->default_value;
BLO_expand(expander, default_value->value);
break;
}
case SOCK_IMAGE: {
- bNodeSocketValueImage *default_value = sock->default_value;
+ bNodeSocketValueImage *default_value = (bNodeSocketValueImage *)sock->default_value;
BLO_expand(expander, default_value->value);
break;
}
case SOCK_COLLECTION: {
- bNodeSocketValueCollection *default_value = sock->default_value;
+ bNodeSocketValueCollection *default_value = (bNodeSocketValueCollection *)
+ sock->default_value;
BLO_expand(expander, default_value->value);
break;
}
@@ -866,28 +879,30 @@ static void ntree_blend_read_expand(BlendExpander *expander, ID *id)
}
IDTypeInfo IDType_ID_NT = {
- .id_code = ID_NT,
- .id_filter = FILTER_ID_NT,
- .main_listbase_index = INDEX_ID_NT,
- .struct_size = sizeof(bNodeTree),
- .name = "NodeTree",
- .name_plural = "node_groups",
- .translation_context = BLT_I18NCONTEXT_ID_NODETREE,
- .flags = 0,
-
- .init_data = ntree_init_data,
- .copy_data = ntree_copy_data,
- .free_data = ntree_free_data,
- .make_local = NULL,
- .foreach_id = node_foreach_id,
- .foreach_cache = node_foreach_cache,
-
- .blend_write = ntree_blend_write,
- .blend_read_data = ntree_blend_read_data,
- .blend_read_lib = ntree_blend_read_lib,
- .blend_read_expand = ntree_blend_read_expand,
-
- .blend_read_undo_preserve = NULL,
+ /* id_code */ ID_NT,
+ /* id_filter */ FILTER_ID_NT,
+ /* main_listbase_index */ INDEX_ID_NT,
+ /* struct_size */ sizeof(bNodeTree),
+ /* name */ "NodeTree",
+ /* name_plural */ "node_groups",
+ /* translation_context */ BLT_I18NCONTEXT_ID_NODETREE,
+ /* flags */ 0,
+
+ /* init_data */ ntree_init_data,
+ /* copy_data */ ntree_copy_data,
+ /* free_data */ ntree_free_data,
+ /* make_local */ nullptr,
+ /* foreach_id */ node_foreach_id,
+ /* foreach_cache */ node_foreach_cache,
+
+ /* blend_write */ ntree_blend_write,
+ /* blend_read_data */ ntree_blend_read_data,
+ /* blend_read_lib */ ntree_blend_read_lib,
+ /* blend_read_expand */ ntree_blend_read_expand,
+
+ /* blend_read_undo_preserve */ nullptr,
+
+ /* lib_override_apply_post */ nullptr,
};
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
@@ -947,11 +962,11 @@ static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
node_add_sockets_from_type(ntree, node, ntype);
- if (ntype->initfunc != NULL) {
+ if (ntype->initfunc != nullptr) {
ntype->initfunc(ntree, node);
}
- if (ntree->typeinfo->node_add_init != NULL) {
+ if (ntree->typeinfo->node_add_init != nullptr) {
ntree->typeinfo->node_add_init(ntree, node);
}
@@ -964,10 +979,10 @@ static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
PointerRNA ptr;
RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
- /* XXX Warning: context can be NULL in case nodes are added in do_versions.
+ /* XXX Warning: context can be nullptr in case nodes are added in do_versions.
* Delayed init is not supported for nodes with context-based initfunc_api atm.
*/
- BLI_assert(C != NULL);
+ BLI_assert(C != nullptr);
ntype->initfunc_api(C, &ptr);
}
@@ -997,7 +1012,7 @@ static void node_set_typeinfo(const struct bContext *C,
/* for nodes saved in older versions storage can get lost, make undefined then */
if (node->flag & NODE_INIT) {
if (typeinfo && typeinfo->storagename[0] && !node->storage) {
- typeinfo = NULL;
+ typeinfo = nullptr;
}
}
@@ -1027,7 +1042,7 @@ static void node_socket_set_typeinfo(bNodeTree *ntree,
/* deprecated integer type */
sock->type = typeinfo->type;
- if (sock->default_value == NULL) {
+ if (sock->default_value == nullptr) {
/* initialize the default_value pointer used by standard socket types */
node_socket_init_default_value(sock);
}
@@ -1055,24 +1070,24 @@ static void update_typeinfo(Main *bmain,
ntree->init |= NTREE_TYPE_INIT;
if (treetype && STREQ(ntree->idname, treetype->idname)) {
- ntree_set_typeinfo(ntree, unregister ? NULL : treetype);
+ ntree_set_typeinfo(ntree, unregister ? nullptr : treetype);
}
/* initialize nodes */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (nodetype && STREQ(node->idname, nodetype->idname)) {
- node_set_typeinfo(C, ntree, node, unregister ? NULL : nodetype);
+ node_set_typeinfo(C, ntree, node, unregister ? nullptr : nodetype);
}
/* initialize node sockets */
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (socktype && STREQ(sock->idname, socktype->idname)) {
- node_socket_set_typeinfo(ntree, sock, unregister ? NULL : socktype);
+ node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
}
}
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
if (socktype && STREQ(sock->idname, socktype->idname)) {
- node_socket_set_typeinfo(ntree, sock, unregister ? NULL : socktype);
+ node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
}
}
}
@@ -1080,12 +1095,12 @@ static void update_typeinfo(Main *bmain,
/* initialize tree sockets */
LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
if (socktype && STREQ(sock->idname, socktype->idname)) {
- node_socket_set_typeinfo(ntree, sock, unregister ? NULL : socktype);
+ node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
}
}
LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
if (socktype && STREQ(sock->idname, socktype->idname)) {
- node_socket_set_typeinfo(ntree, sock, unregister ? NULL : socktype);
+ node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
}
}
}
@@ -1123,22 +1138,20 @@ void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree)
}
}
-static GHash *nodetreetypes_hash = NULL;
-static GHash *nodetypes_hash = NULL;
-static GHash *nodesockettypes_hash = NULL;
+static GHash *nodetreetypes_hash = nullptr;
+static GHash *nodetypes_hash = nullptr;
+static GHash *nodesockettypes_hash = nullptr;
bNodeTreeType *ntreeTypeFind(const char *idname)
{
- bNodeTreeType *nt;
-
if (idname[0]) {
- nt = BLI_ghash_lookup(nodetreetypes_hash, idname);
+ bNodeTreeType *nt = (bNodeTreeType *)BLI_ghash_lookup(nodetreetypes_hash, idname);
if (nt) {
return nt;
}
}
- return NULL;
+ return nullptr;
}
void ntreeTypeAdd(bNodeTreeType *nt)
@@ -1147,23 +1160,23 @@ void ntreeTypeAdd(bNodeTreeType *nt)
/* XXX pass Main to register function? */
/* Probably not. It is pretty much expected we want to update G_MAIN here I think -
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
- update_typeinfo(G_MAIN, NULL, nt, NULL, NULL, false);
+ update_typeinfo(G_MAIN, nullptr, nt, nullptr, nullptr, false);
}
/* callback for hash value free function */
static void ntree_free_type(void *treetype_v)
{
- bNodeTreeType *treetype = treetype_v;
+ bNodeTreeType *treetype = (bNodeTreeType *)treetype_v;
/* XXX pass Main to unregister function? */
/* Probably not. It is pretty much expected we want to update G_MAIN here I think -
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
- update_typeinfo(G_MAIN, NULL, treetype, NULL, NULL, true);
+ update_typeinfo(G_MAIN, nullptr, treetype, nullptr, nullptr, true);
MEM_freeN(treetype);
}
void ntreeTypeFreeLink(const bNodeTreeType *nt)
{
- BLI_ghash_remove(nodetreetypes_hash, nt->idname, NULL, ntree_free_type);
+ BLI_ghash_remove(nodetreetypes_hash, nt->idname, nullptr, ntree_free_type);
}
bool ntreeIsRegistered(bNodeTree *ntree)
@@ -1179,13 +1192,13 @@ GHashIterator *ntreeTypeGetIterator(void)
bNodeType *nodeTypeFind(const char *idname)
{
if (idname[0]) {
- bNodeType *nt = BLI_ghash_lookup(nodetypes_hash, idname);
+ bNodeType *nt = (bNodeType *)BLI_ghash_lookup(nodetypes_hash, idname);
if (nt) {
return nt;
}
}
- return NULL;
+ return nullptr;
}
static void free_dynamic_typeinfo(bNodeType *ntype)
@@ -1203,18 +1216,18 @@ static void free_dynamic_typeinfo(bNodeType *ntype)
/* callback for hash value free function */
static void node_free_type(void *nodetype_v)
{
- bNodeType *nodetype = nodetype_v;
+ bNodeType *nodetype = (bNodeType *)nodetype_v;
/* XXX pass Main to unregister function? */
/* Probably not. It is pretty much expected we want to update G_MAIN here I think -
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
- update_typeinfo(G_MAIN, NULL, NULL, nodetype, NULL, true);
+ update_typeinfo(G_MAIN, nullptr, nullptr, nodetype, nullptr, true);
/* XXX deprecated */
if (nodetype->type == NODE_DYNAMIC) {
free_dynamic_typeinfo(nodetype);
}
- /* Can be NULL when the type is not dynamically allocated. */
+ /* Can be null when the type is not dynamically allocated. */
if (nodetype->free_self) {
nodetype->free_self(nodetype);
}
@@ -1224,18 +1237,18 @@ void nodeRegisterType(bNodeType *nt)
{
/* debug only: basic verification of registered types */
BLI_assert(nt->idname[0] != '\0');
- BLI_assert(nt->poll != NULL);
+ BLI_assert(nt->poll != nullptr);
BLI_ghash_insert(nodetypes_hash, nt->idname, nt);
/* XXX pass Main to register function? */
/* Probably not. It is pretty much expected we want to update G_MAIN here I think -
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
- update_typeinfo(G_MAIN, NULL, NULL, nt, NULL, false);
+ update_typeinfo(G_MAIN, nullptr, nullptr, nt, nullptr, false);
}
void nodeUnregisterType(bNodeType *nt)
{
- BLI_ghash_remove(nodetypes_hash, nt->idname, NULL, node_free_type);
+ BLI_ghash_remove(nodetypes_hash, nt->idname, nullptr, node_free_type);
}
bool nodeTypeUndefined(bNode *node)
@@ -1253,23 +1266,23 @@ GHashIterator *nodeTypeGetIterator(void)
bNodeSocketType *nodeSocketTypeFind(const char *idname)
{
if (idname[0]) {
- bNodeSocketType *st = BLI_ghash_lookup(nodesockettypes_hash, idname);
+ bNodeSocketType *st = (bNodeSocketType *)BLI_ghash_lookup(nodesockettypes_hash, idname);
if (st) {
return st;
}
}
- return NULL;
+ return nullptr;
}
/* callback for hash value free function */
static void node_free_socket_type(void *socktype_v)
{
- bNodeSocketType *socktype = socktype_v;
+ bNodeSocketType *socktype = (bNodeSocketType *)socktype_v;
/* XXX pass Main to unregister function? */
/* Probably not. It is pretty much expected we want to update G_MAIN here I think -
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
- update_typeinfo(G_MAIN, NULL, NULL, NULL, socktype, true);
+ update_typeinfo(G_MAIN, nullptr, nullptr, nullptr, socktype, true);
socktype->free_self(socktype);
}
@@ -1280,12 +1293,12 @@ void nodeRegisterSocketType(bNodeSocketType *st)
/* XXX pass Main to register function? */
/* Probably not. It is pretty much expected we want to update G_MAIN here I think -
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
- update_typeinfo(G_MAIN, NULL, NULL, NULL, st, false);
+ update_typeinfo(G_MAIN, nullptr, nullptr, nullptr, st, false);
}
void nodeUnregisterSocketType(bNodeSocketType *st)
{
- BLI_ghash_remove(nodesockettypes_hash, st->idname, NULL, node_free_socket_type);
+ BLI_ghash_remove(nodesockettypes_hash, st->idname, nullptr, node_free_socket_type);
}
bool nodeSocketIsRegistered(bNodeSocket *sock)
@@ -1306,13 +1319,13 @@ struct bNodeSocket *nodeFindSocket(const bNode *node, int in_out, const char *id
return sock;
}
}
- return NULL;
+ return nullptr;
}
/* find unique socket identifier */
static bool unique_identifier_check(void *arg, const char *identifier)
{
- struct ListBase *lb = arg;
+ const ListBase *lb = (const ListBase *)arg;
LISTBASE_FOREACH (bNodeSocket *, sock, lb) {
if (STREQ(sock->identifier, identifier)) {
return true;
@@ -1343,14 +1356,14 @@ static bNodeSocket *make_socket(bNodeTree *ntree,
BLI_uniquename_cb(
unique_identifier_check, lb, "socket", '.', auto_identifier, sizeof(auto_identifier));
- bNodeSocket *sock = MEM_callocN(sizeof(bNodeSocket), "sock");
+ bNodeSocket *sock = (bNodeSocket *)MEM_callocN(sizeof(bNodeSocket), "sock");
sock->in_out = in_out;
BLI_strncpy(sock->identifier, auto_identifier, NODE_MAXSTR);
sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
BLI_strncpy(sock->name, name, NODE_MAXSTR);
- sock->storage = NULL;
+ sock->storage = nullptr;
sock->flag |= SOCK_COLLAPSED;
sock->type = SOCK_CUSTOM; /* int type undefined by default */
@@ -1364,17 +1377,18 @@ static void socket_id_user_increment(bNodeSocket *sock)
{
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
- bNodeSocketValueObject *default_value = sock->default_value;
+ bNodeSocketValueObject *default_value = (bNodeSocketValueObject *)sock->default_value;
id_us_plus((ID *)default_value->value);
break;
}
case SOCK_IMAGE: {
- bNodeSocketValueImage *default_value = sock->default_value;
+ bNodeSocketValueImage *default_value = (bNodeSocketValueImage *)sock->default_value;
id_us_plus((ID *)default_value->value);
break;
}
case SOCK_COLLECTION: {
- bNodeSocketValueCollection *default_value = sock->default_value;
+ bNodeSocketValueCollection *default_value = (bNodeSocketValueCollection *)
+ sock->default_value;
id_us_plus((ID *)default_value->value);
break;
}
@@ -1396,17 +1410,18 @@ static void socket_id_user_decrement(bNodeSocket *sock)
{
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
- bNodeSocketValueObject *default_value = sock->default_value;
+ bNodeSocketValueObject *default_value = (bNodeSocketValueObject *)sock->default_value;
id_us_min(&default_value->value->id);
break;
}
case SOCK_IMAGE: {
- bNodeSocketValueImage *default_value = sock->default_value;
+ bNodeSocketValueImage *default_value = (bNodeSocketValueImage *)sock->default_value;
id_us_min(&default_value->value->id);
break;
}
case SOCK_COLLECTION: {
- bNodeSocketValueCollection *default_value = sock->default_value;
+ bNodeSocketValueCollection *default_value = (bNodeSocketValueCollection *)
+ sock->default_value;
id_us_min(&default_value->value->id);
break;
}
@@ -1437,7 +1452,7 @@ void nodeModifySocketType(
if (sock->default_value) {
socket_id_user_decrement(sock);
MEM_freeN(sock->default_value);
- sock->default_value = NULL;
+ sock->default_value = nullptr;
}
sock->type = type;
@@ -1552,7 +1567,7 @@ const char *nodeStaticSocketType(int type, int subtype)
case SOCK_COLLECTION:
return "NodeSocketCollection";
}
- return NULL;
+ return nullptr;
}
const char *nodeStaticSocketInterfaceType(int type, int subtype)
@@ -1621,7 +1636,7 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype)
case SOCK_COLLECTION:
return "NodeSocketInterfaceCollection";
}
- return NULL;
+ return nullptr;
}
bNodeSocket *nodeAddStaticSocket(bNodeTree *ntree,
@@ -1636,7 +1651,7 @@ bNodeSocket *nodeAddStaticSocket(bNodeTree *ntree,
if (!idname) {
CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
- return NULL;
+ return nullptr;
}
bNodeSocket *sock = nodeAddSocket(ntree, node, in_out, idname, identifier, name);
@@ -1657,7 +1672,7 @@ bNodeSocket *nodeInsertStaticSocket(bNodeTree *ntree,
if (!idname) {
CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
- return NULL;
+ return nullptr;
}
bNodeSocket *sock = nodeInsertSocket(ntree, node, in_out, idname, next_sock, identifier, name);
@@ -1727,23 +1742,23 @@ void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node)
/* finds a node based on its name */
bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name)
{
- return BLI_findstring(&ntree->nodes, name, offsetof(bNode, name));
+ return (bNode *)BLI_findstring(&ntree->nodes, name, offsetof(bNode, name));
}
/* Finds a node based on given socket and returns true on success. */
bool nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
{
- *r_node = NULL;
+ *r_node = nullptr;
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) {
if (sock == tsock) {
- if (r_node != NULL) {
+ if (r_node != nullptr) {
*r_node = node;
}
- if (r_sockindex != NULL) {
+ if (r_sockindex != nullptr) {
*r_sockindex = index;
}
return true;
@@ -1762,7 +1777,7 @@ bNode *nodeFindRootParent(bNode *node)
if (node->parent) {
return nodeFindRootParent(node->parent);
}
- return node->type == NODE_FRAME ? node : NULL;
+ return node->type == NODE_FRAME ? node : nullptr;
}
/**
@@ -1821,7 +1836,7 @@ static void iter_backwards_ex(const bNodeTree *ntree,
{
LISTBASE_FOREACH (bNodeSocket *, sock, &node_start->inputs) {
bNodeLink *link = sock->link;
- if (link == NULL) {
+ if (link == nullptr) {
continue;
}
if ((link->flag & NODE_LINK_VALID) == 0) {
@@ -1901,7 +1916,7 @@ void nodeUniqueName(bNodeTree *ntree, bNode *node)
bNode *nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idname)
{
- bNode *node = MEM_callocN(sizeof(bNode), "new node");
+ bNode *node = (bNode *)MEM_callocN(sizeof(bNode), "new node");
BLI_addtail(&ntree->nodes, node);
BLI_strncpy(node->idname, idname, sizeof(node->idname));
@@ -1914,7 +1929,7 @@ bNode *nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idnam
bNode *nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
{
- const char *idname = NULL;
+ const char *idname = nullptr;
NODE_TYPES_BEGIN (ntype) {
/* do an extra poll here, because some int types are used
@@ -1928,7 +1943,7 @@ bNode *nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
NODE_TYPES_END;
if (!idname) {
CLOG_ERROR(&LOG, "static node type %d undefined", type);
- return NULL;
+ return nullptr;
}
return nodeAddNode(C, ntree, idname);
}
@@ -1951,7 +1966,7 @@ static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src,
/* XXX some compositor node (e.g. image, render layers) still store
* some persistent buffer data here, need to clear this to avoid dangling pointers.
*/
- sock_dst->cache = NULL;
+ sock_dst->cache = nullptr;
}
/* keep socket listorder identical, for copying links */
@@ -1962,7 +1977,7 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree,
const int flag,
const bool unique_name)
{
- bNode *node_dst = MEM_callocN(sizeof(bNode), "dupli node");
+ bNode *node_dst = (bNode *)MEM_callocN(sizeof(bNode), "dupli node");
bNodeSocket *sock_dst, *sock_src;
bNodeLink *link_dst, *link_src;
@@ -1977,14 +1992,18 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree,
}
BLI_duplicatelist(&node_dst->inputs, &node_src->inputs);
- for (sock_dst = node_dst->inputs.first, sock_src = node_src->inputs.first; sock_dst != NULL;
- sock_dst = sock_dst->next, sock_src = sock_src->next) {
+ for (sock_dst = (bNodeSocket *)node_dst->inputs.first,
+ sock_src = (bNodeSocket *)node_src->inputs.first;
+ sock_dst != nullptr;
+ sock_dst = (bNodeSocket *)sock_dst->next, sock_src = (bNodeSocket *)sock_src->next) {
node_socket_copy(sock_dst, sock_src, flag);
}
BLI_duplicatelist(&node_dst->outputs, &node_src->outputs);
- for (sock_dst = node_dst->outputs.first, sock_src = node_src->outputs.first; sock_dst != NULL;
- sock_dst = sock_dst->next, sock_src = sock_src->next) {
+ for (sock_dst = (bNodeSocket *)node_dst->outputs.first,
+ sock_src = (bNodeSocket *)node_src->outputs.first;
+ sock_dst != nullptr;
+ sock_dst = (bNodeSocket *)sock_dst->next, sock_src = (bNodeSocket *)sock_src->next) {
node_socket_copy(sock_dst, sock_src, flag);
}
@@ -1993,9 +2012,10 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree,
}
BLI_duplicatelist(&node_dst->internal_links, &node_src->internal_links);
- for (link_dst = node_dst->internal_links.first, link_src = node_src->internal_links.first;
- link_dst != NULL;
- link_dst = link_dst->next, link_src = link_src->next) {
+ for (link_dst = (bNodeLink *)node_dst->internal_links.first,
+ link_src = (bNodeLink *)node_src->internal_links.first;
+ link_dst != nullptr;
+ link_dst = (bNodeLink *)link_dst->next, link_src = (bNodeLink *)link_src->next) {
/* This is a bit annoying to do index lookups in a list, but is likely to be faster than
* trying to create a hash-map. At least for usual nodes, which only have so much sockets
* and internal links. */
@@ -2005,8 +2025,8 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree,
BLI_assert(to_sock_index != -1);
link_dst->fromnode = node_dst;
link_dst->tonode = node_dst;
- link_dst->fromsock = BLI_findlink(&node_dst->inputs, from_sock_index);
- link_dst->tosock = BLI_findlink(&node_dst->outputs, to_sock_index);
+ link_dst->fromsock = (bNodeSocket *)BLI_findlink(&node_dst->inputs, from_sock_index);
+ link_dst->tosock = (bNodeSocket *)BLI_findlink(&node_dst->outputs, to_sock_index);
}
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
@@ -2017,7 +2037,7 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree,
node_src->typeinfo->copyfunc(ntree, node_dst, node_src);
}
- node_dst->new_node = NULL;
+ node_dst->new_node = nullptr;
/* Only call copy function when a copy is made for the main database, not
* for cases like the dependency graph and localization. */
@@ -2040,17 +2060,17 @@ static void node_set_new_pointers(bNode *node_src, bNode *new_node)
/* Store mapping to the node itself. */
node_src->new_node = new_node;
/* Store mapping to inputs. */
- bNodeSocket *new_input_sock = new_node->inputs.first;
- bNodeSocket *input_sock_src = node_src->inputs.first;
- while (new_input_sock != NULL) {
+ bNodeSocket *new_input_sock = (bNodeSocket *)new_node->inputs.first;
+ bNodeSocket *input_sock_src = (bNodeSocket *)node_src->inputs.first;
+ while (new_input_sock != nullptr) {
input_sock_src->new_sock = new_input_sock;
new_input_sock = new_input_sock->next;
input_sock_src = input_sock_src->next;
}
/* Store mapping to outputs. */
- bNodeSocket *new_output_sock = new_node->outputs.first;
- bNodeSocket *output_sock_src = node_src->outputs.first;
- while (new_output_sock != NULL) {
+ bNodeSocket *new_output_sock = (bNodeSocket *)new_node->outputs.first;
+ bNodeSocket *output_sock_src = (bNodeSocket *)node_src->outputs.first;
+ while (new_output_sock != nullptr) {
output_sock_src->new_sock = new_output_sock;
new_output_sock = new_output_sock->next;
output_sock_src = output_sock_src->next;
@@ -2069,9 +2089,9 @@ bNodeTree *ntreeCopyTree_ex_new_pointers(const bNodeTree *ntree,
const bool do_id_user)
{
bNodeTree *new_ntree = ntreeCopyTree_ex(ntree, bmain, do_id_user);
- bNode *new_node = new_ntree->nodes.first;
- bNode *node_src = ntree->nodes.first;
- while (new_node != NULL) {
+ bNode *new_node = (bNode *)new_ntree->nodes.first;
+ bNode *node_src = (bNode *)ntree->nodes.first;
+ while (new_node != nullptr) {
node_set_new_pointers(node_src, new_node);
new_node = new_node->next;
node_src = node_src->next;
@@ -2083,14 +2103,14 @@ bNodeTree *ntreeCopyTree_ex_new_pointers(const bNodeTree *ntree,
bNodeLink *nodeAddLink(
bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
{
- bNodeLink *link = NULL;
+ bNodeLink *link = nullptr;
/* test valid input */
BLI_assert(fromnode);
BLI_assert(tonode);
if (fromsock->in_out == SOCK_OUT && tosock->in_out == SOCK_IN) {
- link = MEM_callocN(sizeof(bNodeLink), "link");
+ link = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "link");
if (ntree) {
BLI_addtail(&ntree->links, link);
}
@@ -2101,7 +2121,7 @@ bNodeLink *nodeAddLink(
}
else if (fromsock->in_out == SOCK_IN && tosock->in_out == SOCK_OUT) {
/* OK but flip */
- link = MEM_callocN(sizeof(bNodeLink), "link");
+ link = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "link");
if (ntree) {
BLI_addtail(&ntree->links, link);
}
@@ -2126,7 +2146,7 @@ void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
}
if (link->tosock) {
- link->tosock->link = NULL;
+ link->tosock->link = nullptr;
}
MEM_freeN(link);
@@ -2137,10 +2157,7 @@ void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
{
- bNodeLink *link, *next;
-
- for (link = ntree->links.first; link; link = next) {
- next = link->next;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
if (link->fromsock == sock || link->tosock == sock) {
nodeRemLink(ntree, link);
}
@@ -2149,7 +2166,7 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
ntree->update |= NTREE_UPDATE_LINKS;
}
-bool nodeLinkIsHidden(bNodeLink *link)
+bool nodeLinkIsHidden(const bNodeLink *link)
{
return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock);
}
@@ -2200,7 +2217,7 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
}
}
-void nodeToView(bNode *node, float x, float y, float *rx, float *ry)
+void nodeToView(const bNode *node, float x, float y, float *rx, float *ry)
{
if (node->parent) {
nodeToView(node->parent, x + node->locx, y + node->locy, rx, ry);
@@ -2211,7 +2228,7 @@ void nodeToView(bNode *node, float x, float y, float *rx, float *ry)
}
}
-void nodeFromView(bNode *node, float x, float y, float *rx, float *ry)
+void nodeFromView(const bNode *node, float x, float y, float *rx, float *ry)
{
if (node->parent) {
nodeFromView(node->parent, x, y, rx, ry);
@@ -2224,10 +2241,10 @@ void nodeFromView(bNode *node, float x, float y, float *rx, float *ry)
}
}
-bool nodeAttachNodeCheck(bNode *node, bNode *parent)
+bool nodeAttachNodeCheck(const bNode *node, const bNode *parent)
{
- for (bNode *parent_recurse = node; parent_recurse; parent_recurse = parent_recurse->parent) {
- if (parent_recurse == parent) {
+ for (const bNode *parent_iter = node; parent_iter; parent_iter = parent_iter->parent) {
+ if (parent_iter == parent) {
return true;
}
}
@@ -2258,7 +2275,7 @@ void nodeDetachNode(struct bNode *node)
nodeToView(node, 0.0f, 0.0f, &locx, &locy);
node->locx = locx;
node->locy = locy;
- node->parent = NULL;
+ node->parent = nullptr;
}
}
@@ -2307,7 +2324,7 @@ void nodePositionRelative(bNode *from_node,
void nodePositionPropagate(bNode *node)
{
LISTBASE_FOREACH (bNodeSocket *, nsock, &node->inputs) {
- if (nsock->link != NULL) {
+ if (nsock->link != nullptr) {
bNodeLink *link = nsock->link;
nodePositionRelative(link->fromnode, link->tonode, link->fromsock, link->tosock);
nodePositionPropagate(link->fromnode);
@@ -2317,17 +2334,15 @@ void nodePositionPropagate(bNode *node)
bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
{
- bNodeTree *ntree;
-
/* trees are created as local trees for compositor, material or texture nodes,
* node groups and other tree types are created as library data.
*/
- const bool is_embedded = (bmain == NULL);
+ const bool is_embedded = (bmain == nullptr);
int flag = 0;
if (is_embedded) {
flag |= LIB_ID_CREATE_NO_MAIN;
}
- ntree = BKE_libblock_alloc(bmain, ID_NT, name, flag);
+ bNodeTree *ntree = (bNodeTree *)BKE_libblock_alloc(bmain, ID_NT, name, flag);
if (is_embedded) {
ntree->id.flag |= LIB_EMBEDDED_DATA;
}
@@ -2347,7 +2362,7 @@ bNodeTree *ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_i
{
const int flag = do_id_user ? 0 : LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN;
- bNodeTree *ntree_copy = (bNodeTree *)BKE_id_copy_ex(bmain, (ID *)ntree, NULL, flag);
+ bNodeTree *ntree_copy = (bNodeTree *)BKE_id_copy_ex(bmain, (ID *)ntree, nullptr, flag);
return ntree_copy;
}
bNodeTree *ntreeCopyTree(Main *bmain, const bNodeTree *ntree)
@@ -2362,7 +2377,7 @@ bNodeTree *ntreeCopyTree(Main *bmain, const bNodeTree *ntree)
* using BKE_node_preview_init_tree to set up previews for a whole node tree in advance.
* This should be left more to the individual node tree implementations.
*/
-int BKE_node_preview_used(bNode *node)
+bool BKE_node_preview_used(const bNode *node)
{
/* XXX check for closed nodes? */
return (node->typeinfo->flag & NODE_PREVIEW) != 0;
@@ -2371,14 +2386,14 @@ int BKE_node_preview_used(bNode *node)
bNodePreview *BKE_node_preview_verify(
bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, bool create)
{
- bNodePreview *preview = BKE_node_instance_hash_lookup(previews, key);
+ bNodePreview *preview = (bNodePreview *)BKE_node_instance_hash_lookup(previews, key);
if (!preview) {
if (create) {
- preview = MEM_callocN(sizeof(bNodePreview), "node preview");
+ preview = (bNodePreview *)MEM_callocN(sizeof(bNodePreview), "node preview");
BKE_node_instance_hash_insert(previews, key, preview);
}
else {
- return NULL;
+ return nullptr;
}
}
@@ -2391,12 +2406,13 @@ bNodePreview *BKE_node_preview_verify(
if (preview->rect) {
if (preview->xsize != xsize || preview->ysize != ysize) {
MEM_freeN(preview->rect);
- preview->rect = NULL;
+ preview->rect = nullptr;
}
}
- if (preview->rect == NULL) {
- preview->rect = MEM_callocN(4 * xsize + xsize * ysize * sizeof(char[4]), "node preview rect");
+ if (preview->rect == nullptr) {
+ preview->rect = (unsigned char *)MEM_callocN(4 * xsize + xsize * ysize * sizeof(char[4]),
+ "node preview rect");
preview->xsize = xsize;
preview->ysize = ysize;
}
@@ -2407,9 +2423,9 @@ bNodePreview *BKE_node_preview_verify(
bNodePreview *BKE_node_preview_copy(bNodePreview *preview)
{
- bNodePreview *new_preview = MEM_dupallocN(preview);
+ bNodePreview *new_preview = (bNodePreview *)MEM_dupallocN(preview);
if (preview->rect) {
- new_preview->rect = MEM_dupallocN(preview->rect);
+ new_preview->rect = (unsigned char *)MEM_dupallocN(preview->rect);
}
return new_preview;
}
@@ -2498,7 +2514,7 @@ void BKE_node_preview_free_tree(bNodeTree *ntree)
if (ntree->previews) {
BKE_node_instance_hash_free(ntree->previews, (bNodeInstanceValueFP)BKE_node_preview_free);
- ntree->previews = NULL;
+ ntree->previews = nullptr;
}
}
@@ -2517,7 +2533,7 @@ void BKE_node_preview_clear_tree(bNodeTree *ntree)
bNodeInstanceHashIterator iter;
NODE_INSTANCE_HASH_ITER (iter, ntree->previews) {
- bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
+ bNodePreview *preview = (bNodePreview *)BKE_node_instance_hash_iterator_get_value(&iter);
BKE_node_preview_clear(preview);
}
}
@@ -2547,8 +2563,8 @@ void BKE_node_preview_sync_tree(bNodeTree *to_ntree, bNodeTree *from_ntree)
bNodeInstanceHashIterator iter;
NODE_INSTANCE_HASH_ITER (iter, from_previews) {
bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
- bNodePreview *from = BKE_node_instance_hash_iterator_get_value(&iter);
- bNodePreview *to = BKE_node_instance_hash_lookup(to_previews, key);
+ bNodePreview *from = (bNodePreview *)BKE_node_instance_hash_iterator_get_value(&iter);
+ bNodePreview *to = (bNodePreview *)BKE_node_instance_hash_lookup(to_previews, key);
if (from && to) {
node_preview_sync(to, from);
@@ -2566,7 +2582,7 @@ void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, boo
/* transfer previews */
to_ntree->previews = from_ntree->previews;
- from_ntree->previews = NULL;
+ from_ntree->previews = nullptr;
/* clean up, in case any to_ntree nodes have been removed */
BKE_node_preview_remove_unused(to_ntree);
@@ -2576,7 +2592,7 @@ void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, boo
bNodeInstanceHashIterator iter;
NODE_INSTANCE_HASH_ITER (iter, from_ntree->previews) {
bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
- bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
+ bNodePreview *preview = (bNodePreview *)BKE_node_instance_hash_iterator_get_value(&iter);
/* replace existing previews */
BKE_node_instance_hash_remove(
@@ -2584,10 +2600,10 @@ void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, boo
BKE_node_instance_hash_insert(to_ntree->previews, key, preview);
}
- /* Note: NULL free function here,
+ /* Note: null free function here,
* because pointers have already been moved over to to_ntree->previews! */
- BKE_node_instance_hash_free(from_ntree->previews, NULL);
- from_ntree->previews = NULL;
+ BKE_node_instance_hash_free(from_ntree->previews, nullptr);
+ from_ntree->previews = nullptr;
}
}
}
@@ -2633,7 +2649,7 @@ void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
lb = &node->inputs;
}
else {
- lb = NULL;
+ lb = nullptr;
}
if (lb) {
@@ -2677,7 +2693,7 @@ static void node_free_node(bNodeTree *ntree, bNode *node)
/* texture node has bad habit of keeping exec data around */
if (ntree->type == NTREE_TEXTURE && ntree->execdata) {
ntreeTexEndExecTree(ntree->execdata);
- ntree->execdata = NULL;
+ ntree->execdata = nullptr;
}
}
@@ -2754,7 +2770,7 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", propname_esc);
if (BKE_animdata_fix_paths_remove((ID *)ntree, prefix)) {
- if (bmain != NULL) {
+ if (bmain != nullptr) {
DEG_relations_tag_update(bmain);
}
}
@@ -2826,7 +2842,7 @@ void ntreeFreeLocalTree(bNodeTree *ntree)
void ntreeFreeCache(bNodeTree *ntree)
{
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return;
}
@@ -2925,7 +2941,7 @@ bNodeTree **BKE_ntree_ptr_from_id(ID *id)
case ID_SIM:
return &((Simulation *)id)->nodetree;
default:
- return NULL;
+ return nullptr;
}
}
@@ -2933,10 +2949,10 @@ bNodeTree **BKE_ntree_ptr_from_id(ID *id)
bNodeTree *ntreeFromID(ID *id)
{
bNodeTree **nodetree = BKE_ntree_ptr_from_id(id);
- return (nodetree != NULL) ? *nodetree : NULL;
+ return (nodetree != nullptr) ? *nodetree : nullptr;
}
-/* Finds and returns the datablock that privately owns the given tree, or NULL. */
+/* Finds and returns the datablock that privately owns the given tree, or null. */
ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree)
{
ListBase *lists[] = {&bmain->materials,
@@ -2946,9 +2962,9 @@ ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree)
&bmain->scenes,
&bmain->linestyles,
&bmain->simulations,
- NULL};
+ nullptr};
- for (int i = 0; lists[i] != NULL; i++) {
+ for (int i = 0; lists[i] != nullptr; i++) {
LISTBASE_FOREACH (ID *, id, lists[i]) {
if (ntreeFromID(id) == ntree) {
return id;
@@ -2956,12 +2972,12 @@ ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree)
}
}
- return NULL;
+ return nullptr;
}
-bool ntreeNodeExists(bNodeTree *ntree, bNode *testnode)
+bool ntreeNodeExists(const bNodeTree *ntree, const bNode *testnode)
{
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ LISTBASE_FOREACH (const bNode *, node, &ntree->nodes) {
if (node == testnode) {
return true;
}
@@ -2969,9 +2985,9 @@ bool ntreeNodeExists(bNodeTree *ntree, bNode *testnode)
return false;
}
-bool ntreeOutputExists(bNode *node, bNodeSocket *testsock)
+bool ntreeOutputExists(const bNode *node, const bNodeSocket *testsock)
{
- LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
+ LISTBASE_FOREACH (const bNodeSocket *, sock, &node->outputs) {
if (sock == testsock) {
return true;
}
@@ -2999,7 +3015,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
* Note: previews are not copied here.
*/
bNodeTree *ltree = (bNodeTree *)BKE_id_copy_ex(
- NULL, &ntree->id, NULL, (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA));
+ nullptr, &ntree->id, nullptr, (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA));
ltree->id.tag |= LIB_TAG_LOCALIZED;
@@ -3012,9 +3028,9 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
/* ensures only a single output node is enabled */
ntreeSetOutput(ntree);
- bNode *node_src = ntree->nodes.first;
- bNode *node_local = ltree->nodes.first;
- while (node_src != NULL) {
+ bNode *node_src = (bNode *)ntree->nodes.first;
+ bNode *node_local = (bNode *)ltree->nodes.first;
+ while (node_src != nullptr) {
node_local->original = node_src;
node_src = node_src->next;
node_local = node_local->next;
@@ -3027,7 +3043,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
return ltree;
}
- return NULL;
+ return nullptr;
}
/* sync local composite with real tree */
@@ -3066,11 +3082,11 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree,
bNodeSocketType *stype = nodeSocketTypeFind(idname);
int own_index = ntree->cur_index++;
- if (stype == NULL) {
- return NULL;
+ if (stype == nullptr) {
+ return nullptr;
}
- bNodeSocket *sock = MEM_callocN(sizeof(bNodeSocket), "socket template");
+ bNodeSocket *sock = (bNodeSocket *)MEM_callocN(sizeof(bNodeSocket), "socket template");
BLI_strncpy(sock->idname, stype->idname, sizeof(sock->idname));
node_socket_set_typeinfo(ntree, sock, stype);
sock->in_out = in_out;
@@ -3089,7 +3105,7 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree,
sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
BLI_strncpy(sock->name, name, NODE_MAXSTR);
- sock->storage = NULL;
+ sock->storage = nullptr;
sock->flag |= SOCK_COLLAPSED;
return sock;
@@ -3103,7 +3119,7 @@ bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, int in_out, const char *
return iosock;
}
}
- return NULL;
+ return nullptr;
}
bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree,
@@ -3190,7 +3206,7 @@ static void ntree_interface_identifier_base(bNodeTree *ntree, char *base)
/* check if the identifier is already in use */
static bool ntree_interface_unique_identifier_check(void *UNUSED(data), const char *identifier)
{
- return (RNA_struct_find(identifier) != NULL);
+ return (RNA_struct_find(identifier) != nullptr);
}
/* generates the actual unique identifier and ui name and description */
@@ -3206,7 +3222,8 @@ static void ntree_interface_identifier(bNodeTree *ntree,
* On top of the sanitized id string add a number suffix if necessary to avoid duplicates.
*/
identifier[0] = '\0';
- BLI_uniquename_cb(ntree_interface_unique_identifier_check, NULL, base, '_', identifier, maxlen);
+ 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);
@@ -3246,7 +3263,7 @@ static void ntree_interface_type_create(bNodeTree *ntree)
}
}
-StructRNA *ntreeInterfaceTypeGet(bNodeTree *ntree, int create)
+StructRNA *ntreeInterfaceTypeGet(bNodeTree *ntree, bool create)
{
if (ntree->interface_type) {
/* strings are generated from base string + ID name, sizes are sufficient */
@@ -3284,7 +3301,7 @@ void ntreeInterfaceTypeFree(bNodeTree *ntree)
{
if (ntree->interface_type) {
RNA_struct_free(&BLENDER_RNA, ntree->interface_type);
- ntree->interface_type = NULL;
+ ntree->interface_type = nullptr;
}
}
@@ -3310,12 +3327,12 @@ bNode *ntreeFindType(const bNodeTree *ntree, int type)
}
}
}
- return NULL;
+ return nullptr;
}
bool ntreeHasType(const bNodeTree *ntree, int type)
{
- return ntreeFindType(ntree, type) != NULL;
+ return ntreeFindType(ntree, type) != nullptr;
}
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
@@ -3333,7 +3350,7 @@ bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
return false;
}
-bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
+bNodeLink *nodeFindLink(bNodeTree *ntree, const bNodeSocket *from, const bNodeSocket *to)
{
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
if (link->fromsock == from && link->tosock == to) {
@@ -3343,13 +3360,13 @@ bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
return link;
}
}
- return NULL;
+ return nullptr;
}
-int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
+int nodeCountSocketLinks(const bNodeTree *ntree, const bNodeSocket *sock)
{
int tot = 0;
- LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ LISTBASE_FOREACH (const bNodeLink *, link, &ntree->links) {
if (link->fromsock == sock || link->tosock == sock) {
tot++;
}
@@ -3359,8 +3376,8 @@ int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
bNode *nodeGetActive(bNodeTree *ntree)
{
- if (ntree == NULL) {
- return NULL;
+ if (ntree == nullptr) {
+ return nullptr;
}
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@@ -3368,7 +3385,7 @@ bNode *nodeGetActive(bNodeTree *ntree)
return node;
}
}
- return NULL;
+ return nullptr;
}
static bNode *node_get_active_id_recursive(bNodeInstanceKey active_key,
@@ -3400,7 +3417,7 @@ static bNode *node_get_active_id_recursive(bNodeInstanceKey active_key,
}
}
}
- return NULL;
+ return nullptr;
}
/* two active flags, ID nodes have special flag for buttons display */
@@ -3410,14 +3427,14 @@ bNode *nodeGetActiveID(bNodeTree *ntree, short idtype)
return node_get_active_id_recursive(
ntree->active_viewer_key, NODE_INSTANCE_KEY_BASE, ntree, idtype);
}
- return NULL;
+ return nullptr;
}
bool nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
{
bool ok = false;
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return ok;
}
@@ -3435,11 +3452,11 @@ bool nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
/* update all groups linked from here
* if active ID node has been found already,
- * just pass NULL so other matching nodes are deactivated.
+ * just pass null so other matching nodes are deactivated.
*/
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type == NODE_GROUP) {
- ok |= nodeSetActiveID((bNodeTree *)node->id, idtype, (ok == false ? id : NULL));
+ ok |= nodeSetActiveID((bNodeTree *)node->id, idtype, (ok == false ? id : nullptr));
}
}
@@ -3449,7 +3466,7 @@ bool nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
/* two active flags, ID nodes have special flag for buttons display */
void nodeClearActiveID(bNodeTree *ntree, short idtype)
{
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return;
}
@@ -3480,7 +3497,7 @@ void nodeSetSelected(bNode *node, bool select)
void nodeClearActive(bNodeTree *ntree)
{
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return;
}
@@ -3515,7 +3532,7 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
}
}
-int nodeSocketIsHidden(bNodeSocket *sock)
+int nodeSocketIsHidden(const bNodeSocket *sock)
{
return ((sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) != 0);
}
@@ -3530,10 +3547,13 @@ void nodeSetSocketAvailability(bNodeSocket *sock, bool is_available)
}
}
-int nodeSocketLinkLimit(struct bNodeSocket *sock)
+int nodeSocketLinkLimit(const bNodeSocket *sock)
{
bNodeSocketType *stype = sock->typeinfo;
- if (stype != NULL && stype->use_link_limits_of_type) {
+ if (sock->flag & SOCK_MULTI_INPUT) {
+ return 4095;
+ }
+ if (stype != nullptr && stype->use_link_limits_of_type) {
int limit = (sock->in_out == SOCK_IN) ? stype->input_link_limit : stype->output_link_limit;
return limit;
}
@@ -3553,15 +3573,15 @@ int nodeSocketLinkLimit(struct bNodeSocket *sock)
* Currently its only used for ID's, but nodes may one day
* reference other pointers which need validation.
*/
-typedef struct bNodeClipboardExtraInfo {
+struct bNodeClipboardExtraInfo {
struct bNodeClipboardExtraInfo *next, *prev;
ID *id;
char id_name[MAX_ID_NAME];
char library_name[FILE_MAX];
-} bNodeClipboardExtraInfo;
+};
#endif /* USE_NODE_CB_VALIDATE */
-typedef struct bNodeClipboard {
+struct bNodeClipboard {
ListBase nodes;
#ifdef USE_NODE_CB_VALIDATE
@@ -3570,11 +3590,11 @@ typedef struct bNodeClipboard {
ListBase links;
int type;
-} bNodeClipboard;
+};
-static bNodeClipboard node_clipboard = {{NULL}};
+static bNodeClipboard node_clipboard = {{nullptr}};
-void BKE_node_clipboard_init(struct bNodeTree *ntree)
+void BKE_node_clipboard_init(const struct bNodeTree *ntree)
{
node_clipboard.type = ntree->type;
}
@@ -3582,12 +3602,12 @@ void BKE_node_clipboard_init(struct bNodeTree *ntree)
void BKE_node_clipboard_clear(void)
{
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &node_clipboard.links) {
- nodeRemLink(NULL, link);
+ nodeRemLink(nullptr, link);
}
BLI_listbase_clear(&node_clipboard.links);
LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_clipboard.nodes) {
- node_free_node(NULL, node);
+ node_free_node(nullptr, node);
}
BLI_listbase_clear(&node_clipboard.nodes);
@@ -3609,8 +3629,10 @@ bool BKE_node_clipboard_validate(void)
BLI_assert(BLI_listbase_count(&node_clipboard.nodes) ==
BLI_listbase_count(&node_clipboard.nodes_extra_info));
- for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first; node;
- node = node->next, node_info = node_info->next) {
+ for (node = (bNode *)node_clipboard.nodes.first,
+ node_info = (bNodeClipboardExtraInfo *)node_clipboard.nodes_extra_info.first;
+ node;
+ node = (bNode *)node->next, node_info = (bNodeClipboardExtraInfo *)node_info->next) {
/* validate the node against the stored node info */
/* re-assign each loop since we may clear,
@@ -3621,13 +3643,13 @@ bool BKE_node_clipboard_validate(void)
if (node->id) {
/* We want to search into current blend file, so using G_MAIN is valid here too. */
ListBase *lb = which_libbase(G_MAIN, GS(node_info->id_name));
- BLI_assert(lb != NULL);
+ BLI_assert(lb != nullptr);
if (BLI_findindex(lb, node_info->id) == -1) {
- /* may assign NULL */
- node->id = BLI_findstring(lb, node_info->id_name + 2, offsetof(ID, name) + 2);
+ /* May assign null. */
+ node->id = (ID *)BLI_findstring(lb, node_info->id_name + 2, offsetof(ID, name) + 2);
- if (node->id == NULL) {
+ if (node->id == nullptr) {
ok = false;
}
}
@@ -3642,8 +3664,8 @@ void BKE_node_clipboard_add_node(bNode *node)
{
#ifdef USE_NODE_CB_VALIDATE
/* add extra info */
- bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo),
- "bNodeClipboardExtraInfo");
+ bNodeClipboardExtraInfo *node_info = (bNodeClipboardExtraInfo *)MEM_mallocN(
+ sizeof(bNodeClipboardExtraInfo), __func__);
node_info->id = node->id;
if (node->id) {
@@ -3718,11 +3740,11 @@ static bNodeInstanceKey node_hash_int_str(bNodeInstanceKey hash, const char *str
return hash;
}
-bNodeInstanceKey BKE_node_instance_key(bNodeInstanceKey parent_key, bNodeTree *ntree, bNode *node)
+bNodeInstanceKey BKE_node_instance_key(bNodeInstanceKey parent_key,
+ const bNodeTree *ntree,
+ const bNode *node)
{
- bNodeInstanceKey key;
-
- key = node_hash_int_str(parent_key, ntree->id.name + 2);
+ bNodeInstanceKey key = node_hash_int_str(parent_key, ntree->id.name + 2);
if (node) {
key = node_hash_int_str(key, node->name);
@@ -3746,7 +3768,7 @@ static bool node_instance_hash_key_cmp(const void *a, const void *b)
bNodeInstanceHash *BKE_node_instance_hash_new(const char *info)
{
- bNodeInstanceHash *hash = MEM_mallocN(sizeof(bNodeInstanceHash), info);
+ bNodeInstanceHash *hash = (bNodeInstanceHash *)MEM_mallocN(sizeof(bNodeInstanceHash), info);
hash->ghash = BLI_ghash_new(
node_instance_hash_key, node_instance_hash_key_cmp, "node instance hash ghash");
return hash;
@@ -3754,13 +3776,13 @@ bNodeInstanceHash *BKE_node_instance_hash_new(const char *info)
void BKE_node_instance_hash_free(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
{
- BLI_ghash_free(hash->ghash, NULL, (GHashValFreeFP)valfreefp);
+ BLI_ghash_free(hash->ghash, nullptr, (GHashValFreeFP)valfreefp);
MEM_freeN(hash);
}
void BKE_node_instance_hash_insert(bNodeInstanceHash *hash, bNodeInstanceKey key, void *value)
{
- bNodeInstanceHashEntry *entry = value;
+ bNodeInstanceHashEntry *entry = (bNodeInstanceHashEntry *)value;
entry->key = key;
entry->tag = 0;
BLI_ghash_insert(hash->ghash, &entry->key, value);
@@ -3775,17 +3797,17 @@ int BKE_node_instance_hash_remove(bNodeInstanceHash *hash,
bNodeInstanceKey key,
bNodeInstanceValueFP valfreefp)
{
- return BLI_ghash_remove(hash->ghash, &key, NULL, (GHashValFreeFP)valfreefp);
+ return BLI_ghash_remove(hash->ghash, &key, nullptr, (GHashValFreeFP)valfreefp);
}
void BKE_node_instance_hash_clear(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
{
- BLI_ghash_clear(hash->ghash, NULL, (GHashValFreeFP)valfreefp);
+ BLI_ghash_clear(hash->ghash, nullptr, (GHashValFreeFP)valfreefp);
}
void *BKE_node_instance_hash_pop(bNodeInstanceHash *hash, bNodeInstanceKey key)
{
- return BLI_ghash_popkey(hash->ghash, &key, NULL);
+ return BLI_ghash_popkey(hash->ghash, &key, nullptr);
}
int BKE_node_instance_hash_haskey(bNodeInstanceHash *hash, bNodeInstanceKey key)
@@ -3803,7 +3825,8 @@ void BKE_node_instance_hash_clear_tags(bNodeInstanceHash *hash)
bNodeInstanceHashIterator iter;
NODE_INSTANCE_HASH_ITER (iter, hash) {
- bNodeInstanceHashEntry *value = BKE_node_instance_hash_iterator_get_value(&iter);
+ bNodeInstanceHashEntry *value = (bNodeInstanceHashEntry *)
+ BKE_node_instance_hash_iterator_get_value(&iter);
value->tag = 0;
}
@@ -3811,13 +3834,14 @@ void BKE_node_instance_hash_clear_tags(bNodeInstanceHash *hash)
void BKE_node_instance_hash_tag(bNodeInstanceHash *UNUSED(hash), void *value)
{
- bNodeInstanceHashEntry *entry = value;
+ bNodeInstanceHashEntry *entry = (bNodeInstanceHashEntry *)value;
entry->tag = 1;
}
bool BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey key)
{
- bNodeInstanceHashEntry *entry = BKE_node_instance_hash_lookup(hash, key);
+ bNodeInstanceHashEntry *entry = (bNodeInstanceHashEntry *)BKE_node_instance_hash_lookup(hash,
+ key);
if (entry) {
entry->tag = 1;
@@ -3833,13 +3857,14 @@ void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash,
/* NOTE: Hash must not be mutated during iterating!
* Store tagged entries in a separate list and remove items afterward.
*/
- bNodeInstanceKey *untagged = MEM_mallocN(sizeof(bNodeInstanceKey) *
- BKE_node_instance_hash_size(hash),
- "temporary node instance key list");
+ bNodeInstanceKey *untagged = (bNodeInstanceKey *)MEM_mallocN(
+ sizeof(bNodeInstanceKey) * BKE_node_instance_hash_size(hash),
+ "temporary node instance key list");
bNodeInstanceHashIterator iter;
int num_untagged = 0;
NODE_INSTANCE_HASH_ITER (iter, hash) {
- bNodeInstanceHashEntry *value = BKE_node_instance_hash_iterator_get_value(&iter);
+ bNodeInstanceHashEntry *value = (bNodeInstanceHashEntry *)
+ BKE_node_instance_hash_iterator_get_value(&iter);
if (!value->tag) {
untagged[num_untagged++] = BKE_node_instance_hash_iterator_get_key(&iter);
@@ -3893,22 +3918,23 @@ static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort
return level;
}
-void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes)
+void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist, int *r_deplist_len)
{
- *totnodes = 0;
+ *r_deplist_len = 0;
/* first clear data */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->done = false;
- (*totnodes)++;
+ (*r_deplist_len)++;
}
- if (*totnodes == 0) {
- *deplist = NULL;
+ if (*r_deplist_len == 0) {
+ *r_deplist = nullptr;
return;
}
bNode **nsort;
- nsort = *deplist = MEM_callocN((*totnodes) * sizeof(bNode *), "sorted node array");
+ nsort = *r_deplist = (bNode **)MEM_callocN((*r_deplist_len) * sizeof(bNode *),
+ "sorted node array");
/* recursive check */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@@ -3929,7 +3955,7 @@ static void ntree_update_node_level(bNodeTree *ntree)
/* recursive check */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->done == 0) {
- node->level = node_get_deplist_recurs(ntree, node, NULL);
+ node->level = node_get_deplist_recurs(ntree, node, nullptr);
}
}
}
@@ -3957,7 +3983,7 @@ static void ntree_update_link_pointers(bNodeTree *ntree)
/* first clear data */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
- sock->link = NULL;
+ sock->link = nullptr;
}
}
@@ -3996,7 +4022,7 @@ void ntreeUpdateAllNew(Main *main)
}
}
- ntreeUpdateTree(NULL, ntree);
+ ntreeUpdateTree(nullptr, ntree);
}
}
FOREACH_NODETREE_END;
@@ -4004,7 +4030,7 @@ void ntreeUpdateAllNew(Main *main)
void ntreeUpdateAllUsers(Main *main, ID *id)
{
- if (id == NULL) {
+ if (id == nullptr) {
return;
}
@@ -4023,7 +4049,7 @@ void ntreeUpdateAllUsers(Main *main, ID *id)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ ntreeUpdateTree(nullptr, ntree);
}
}
FOREACH_NODETREE_END;
@@ -4133,7 +4159,7 @@ bool nodeUpdateID(bNodeTree *ntree, ID *id)
{
bool changed = false;
- if (ELEM(NULL, id, ntree)) {
+ if (ELEM(nullptr, id, ntree)) {
return changed;
}
@@ -4237,7 +4263,7 @@ void node_type_base(bNodeType *ntype, int type, const char *name, short nclass,
case ID: \
BLI_strncpy(ntype->idname, #Category #StructName, sizeof(ntype->idname)); \
ntype->rna_ext.srna = RNA_struct_find(#Category #StructName); \
- BLI_assert(ntype->rna_ext.srna != NULL); \
+ BLI_assert(ntype->rna_ext.srna != nullptr); \
RNA_struct_blender_type_set(ntype->rna_ext.srna, ntype); \
break;
@@ -4271,15 +4297,16 @@ void node_type_base_custom(
node_type_base_defaults(ntype);
}
+struct SocketTemplateIdentifierCallbackData {
+ bNodeSocketTemplate *list;
+ bNodeSocketTemplate *ntemp;
+};
+
static bool unique_socket_template_identifier_check(void *arg, const char *name)
{
- bNodeSocketTemplate *ntemp;
- struct {
- bNodeSocketTemplate *list;
- bNodeSocketTemplate *ntemp;
- } *data = arg;
+ SocketTemplateIdentifierCallbackData *data = (SocketTemplateIdentifierCallbackData *)arg;
- for (ntemp = data->list; ntemp->type >= 0; ntemp++) {
+ for (bNodeSocketTemplate *ntemp = data->list; ntemp->type >= 0; ntemp++) {
if (ntemp != data->ntemp) {
if (STREQ(ntemp->identifier, name)) {
return true;
@@ -4295,10 +4322,7 @@ static void unique_socket_template_identifier(bNodeSocketTemplate *list,
const char defname[],
char delim)
{
- struct {
- bNodeSocketTemplate *list;
- bNodeSocketTemplate *ntemp;
- } data;
+ SocketTemplateIdentifierCallbackData data;
data.list = list;
data.ntemp = ntemp;
@@ -4448,7 +4472,7 @@ static bool node_undefined_poll(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(node
}
/* register fallback types used for undefined tree, nodes, sockets */
-static void register_undefined_types(void)
+static void register_undefined_types()
{
/* Note: these types are not registered in the type hashes,
* they are just used as placeholders in case the actual types are not registered.
@@ -4473,7 +4497,7 @@ static void register_undefined_types(void)
NodeSocketTypeUndefined.output_link_limit = 0xFFF;
}
-static void registerCompositNodes(void)
+static void registerCompositNodes()
{
register_node_type_cmp_group();
@@ -4577,7 +4601,7 @@ static void registerCompositNodes(void)
register_node_type_cmp_cornerpin();
}
-static void registerShaderNodes(void)
+static void registerShaderNodes()
{
register_node_type_sh_group();
@@ -4674,7 +4698,7 @@ static void registerShaderNodes(void)
register_node_type_sh_tex_white_noise();
}
-static void registerTextureNodes(void)
+static void registerTextureNodes()
{
register_node_type_tex_group();
@@ -4724,43 +4748,51 @@ static void registerTextureNodes(void)
register_node_type_tex_proc_distnoise();
}
-static void registerGeometryNodes(void)
+static void registerGeometryNodes()
{
register_node_type_geo_group();
+ register_node_type_geo_align_rotation_to_vector();
+ register_node_type_geo_attribute_color_ramp();
+ register_node_type_geo_attribute_combine_xyz();
register_node_type_geo_attribute_compare();
register_node_type_geo_attribute_fill();
+ register_node_type_geo_attribute_math();
+ register_node_type_geo_attribute_mix();
+ register_node_type_geo_attribute_proximity();
+ register_node_type_geo_attribute_randomize();
+ register_node_type_geo_attribute_separate_xyz();
register_node_type_geo_attribute_vector_math();
- register_node_type_geo_triangulate();
- register_node_type_geo_edge_split();
- register_node_type_geo_transform();
- register_node_type_geo_subdivision_surface();
register_node_type_geo_boolean();
+ register_node_type_geo_collection_info();
+ register_node_type_geo_edge_split();
+ register_node_type_geo_is_viewport();
+ register_node_type_geo_join_geometry();
+ register_node_type_geo_object_info();
register_node_type_geo_point_distribute();
register_node_type_geo_point_instance();
- register_node_type_geo_point_separate();
+ register_node_type_geo_point_rotate();
register_node_type_geo_point_scale();
+ register_node_type_geo_point_separate();
register_node_type_geo_point_translate();
- register_node_type_geo_object_info();
- register_node_type_geo_attribute_randomize();
- register_node_type_geo_attribute_math();
- register_node_type_geo_join_geometry();
- register_node_type_geo_attribute_mix();
- register_node_type_geo_attribute_color_ramp();
- register_node_type_geo_point_rotate();
- register_node_type_geo_align_rotation_to_vector();
+ register_node_type_geo_points_to_volume();
+ register_node_type_geo_sample_texture();
+ register_node_type_geo_subdivision_surface();
+ register_node_type_geo_transform();
+ register_node_type_geo_triangulate();
+ register_node_type_geo_volume_to_mesh();
}
-static void registerFunctionNodes(void)
+static void registerFunctionNodes()
{
register_node_type_fn_boolean_math();
+ register_node_type_fn_combine_strings();
register_node_type_fn_float_compare();
- register_node_type_fn_switch();
register_node_type_fn_group_instance_id();
- register_node_type_fn_combine_strings();
+ register_node_type_fn_input_vector();
register_node_type_fn_object_transforms();
register_node_type_fn_random_float();
- register_node_type_fn_input_vector();
+ register_node_type_fn_switch();
}
void BKE_node_system_init(void)
@@ -4800,8 +4832,8 @@ void BKE_node_system_exit(void)
}
NODE_TYPES_END;
- BLI_ghash_free(nodetypes_hash, NULL, node_free_type);
- nodetypes_hash = NULL;
+ BLI_ghash_free(nodetypes_hash, nullptr, node_free_type);
+ nodetypes_hash = nullptr;
}
if (nodesockettypes_hash) {
@@ -4815,8 +4847,8 @@ void BKE_node_system_exit(void)
}
NODE_SOCKET_TYPES_END;
- BLI_ghash_free(nodesockettypes_hash, NULL, node_free_socket_type);
- nodesockettypes_hash = NULL;
+ BLI_ghash_free(nodesockettypes_hash, nullptr, node_free_socket_type);
+ nodesockettypes_hash = nullptr;
}
if (nodetreetypes_hash) {
@@ -4827,8 +4859,8 @@ void BKE_node_system_exit(void)
}
NODE_TREE_TYPES_END;
- BLI_ghash_free(nodetreetypes_hash, NULL, ntree_free_type);
- nodetreetypes_hash = NULL;
+ BLI_ghash_free(nodetreetypes_hash, nullptr, ntree_free_type);
+ nodetreetypes_hash = nullptr;
}
}
@@ -4837,58 +4869,58 @@ void BKE_node_system_exit(void)
void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *bmain)
{
- ntreeiter->ngroup = bmain->nodetrees.first;
- ntreeiter->scene = bmain->scenes.first;
- ntreeiter->mat = bmain->materials.first;
- ntreeiter->tex = bmain->textures.first;
- ntreeiter->light = bmain->lights.first;
- ntreeiter->world = bmain->worlds.first;
- ntreeiter->linestyle = bmain->linestyles.first;
- ntreeiter->simulation = bmain->simulations.first;
+ ntreeiter->ngroup = (bNodeTree *)bmain->nodetrees.first;
+ ntreeiter->scene = (Scene *)bmain->scenes.first;
+ ntreeiter->mat = (Material *)bmain->materials.first;
+ ntreeiter->tex = (Tex *)bmain->textures.first;
+ ntreeiter->light = (Light *)bmain->lights.first;
+ ntreeiter->world = (World *)bmain->worlds.first;
+ ntreeiter->linestyle = (FreestyleLineStyle *)bmain->linestyles.first;
+ ntreeiter->simulation = (Simulation *)bmain->simulations.first;
}
bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
bNodeTree **r_nodetree,
struct ID **r_id)
{
if (ntreeiter->ngroup) {
- *r_nodetree = ntreeiter->ngroup;
+ *r_nodetree = (bNodeTree *)ntreeiter->ngroup;
*r_id = (ID *)ntreeiter->ngroup;
- ntreeiter->ngroup = ntreeiter->ngroup->id.next;
+ ntreeiter->ngroup = (bNodeTree *)ntreeiter->ngroup->id.next;
}
else if (ntreeiter->scene) {
- *r_nodetree = ntreeiter->scene->nodetree;
+ *r_nodetree = (bNodeTree *)ntreeiter->scene->nodetree;
*r_id = (ID *)ntreeiter->scene;
- ntreeiter->scene = ntreeiter->scene->id.next;
+ ntreeiter->scene = (Scene *)ntreeiter->scene->id.next;
}
else if (ntreeiter->mat) {
- *r_nodetree = ntreeiter->mat->nodetree;
+ *r_nodetree = (bNodeTree *)ntreeiter->mat->nodetree;
*r_id = (ID *)ntreeiter->mat;
- ntreeiter->mat = ntreeiter->mat->id.next;
+ ntreeiter->mat = (Material *)ntreeiter->mat->id.next;
}
else if (ntreeiter->tex) {
- *r_nodetree = ntreeiter->tex->nodetree;
+ *r_nodetree = (bNodeTree *)ntreeiter->tex->nodetree;
*r_id = (ID *)ntreeiter->tex;
- ntreeiter->tex = ntreeiter->tex->id.next;
+ ntreeiter->tex = (Tex *)ntreeiter->tex->id.next;
}
else if (ntreeiter->light) {
- *r_nodetree = ntreeiter->light->nodetree;
+ *r_nodetree = (bNodeTree *)ntreeiter->light->nodetree;
*r_id = (ID *)ntreeiter->light;
- ntreeiter->light = ntreeiter->light->id.next;
+ ntreeiter->light = (Light *)ntreeiter->light->id.next;
}
else if (ntreeiter->world) {
- *r_nodetree = ntreeiter->world->nodetree;
+ *r_nodetree = (bNodeTree *)ntreeiter->world->nodetree;
*r_id = (ID *)ntreeiter->world;
- ntreeiter->world = ntreeiter->world->id.next;
+ ntreeiter->world = (World *)ntreeiter->world->id.next;
}
else if (ntreeiter->linestyle) {
- *r_nodetree = ntreeiter->linestyle->nodetree;
+ *r_nodetree = (bNodeTree *)ntreeiter->linestyle->nodetree;
*r_id = (ID *)ntreeiter->linestyle;
- ntreeiter->linestyle = ntreeiter->linestyle->id.next;
+ ntreeiter->linestyle = (FreestyleLineStyle *)ntreeiter->linestyle->id.next;
}
else if (ntreeiter->simulation) {
- *r_nodetree = ntreeiter->simulation->nodetree;
+ *r_nodetree = (bNodeTree *)ntreeiter->simulation->nodetree;
*r_id = (ID *)ntreeiter->simulation;
- ntreeiter->simulation = ntreeiter->simulation->id.next;
+ ntreeiter->simulation = (Simulation *)ntreeiter->simulation->id.next;
}
else {
return false;
@@ -4914,10 +4946,3 @@ void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer
}
}
}
-
-void BKE_nodetree_shading_params_eval(struct Depsgraph *depsgraph,
- bNodeTree *ntree_dst,
- const bNodeTree *ntree_src)
-{
- DEG_debug_print_eval(depsgraph, __func__, ntree_src->id.name, ntree_dst);
-}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 70af46569a8..9b5a1614dc0 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1118,6 +1118,20 @@ static void object_blend_read_expand(BlendExpander *expander, ID *id)
}
}
+static void object_lib_override_apply_post(ID *id_dst, ID *UNUSED(id_src))
+{
+ Object *object = (Object *)id_dst;
+
+ ListBase pidlist;
+ BKE_ptcache_ids_from_object(&pidlist, object, NULL, 0);
+ LISTBASE_FOREACH (PTCacheID *, pid, &pidlist) {
+ LISTBASE_FOREACH (PointCache *, point_cache, pid->ptcaches) {
+ point_cache->flag |= PTCACHE_FLAG_INFO_DIRTY;
+ }
+ }
+ BLI_freelistN(&pidlist);
+}
+
IDTypeInfo IDType_ID_OB = {
.id_code = ID_OB,
.id_filter = FILTER_ID_OB,
@@ -1141,6 +1155,8 @@ IDTypeInfo IDType_ID_OB = {
.blend_read_expand = object_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = object_lib_override_apply_post,
};
void BKE_object_workob_clear(Object *workob)
@@ -1506,11 +1522,11 @@ bool BKE_object_copy_gpencil_modifier(struct Object *ob_dst, GpencilModifierData
/**
* Copy the whole stack of modifiers from one object into another.
*
- * \warning **Does not** clear modifier stack and related data (particle systems, softbody,
+ * \warning **Does not** clear modifier stack and related data (particle systems, soft-body,
* etc.) in `ob_dst`, if needed calling code must do it.
*
- * @param do_copy_all If true, even modifiers that should not suport copying (like Hook one) will
- * be duplicated.
+ * \param do_copy_all: If true, even modifiers that should not support copying (like Hook one)
+ * will be duplicated.
*/
bool BKE_object_modifier_stack_copy(Object *ob_dst,
const Object *ob_src,
@@ -3528,9 +3544,6 @@ static void solve_parenting(
}
}
-/**
- * \note scene is the active scene while actual_scene is the scene the object resides in.
- */
static void object_where_is_calc_ex(Depsgraph *depsgraph,
Scene *scene,
Object *ob,
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 1d79f871fa2..69442b7646c 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -225,7 +225,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
case OB_GPENCIL: {
BKE_gpencil_prepare_eval_data(depsgraph, scene, ob);
BKE_gpencil_modifiers_calc(depsgraph, scene, ob);
- BKE_gpencil_update_layer_parent(depsgraph, ob);
+ BKE_gpencil_update_layer_transforms(depsgraph, ob);
break;
}
case OB_HAIR:
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 1d62a1cce2a..d2f4d0702ed 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -140,7 +140,7 @@ static void compute_eigenstuff(struct OceanResult *ocr, float jxx, float jzz, fl
* instead of Complex.h
* in fftw.h "fftw_complex" typedefed as double[2]
* below you can see functions are needed to work with such complex numbers.
- * */
+ */
static void init_complex(fftw_complex cmpl, float real, float image)
{
cmpl[0] = real;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 7c65f118cf4..3c770a85b2a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -127,7 +127,7 @@ static void palette_blend_read_data(BlendDataReader *reader, ID *id)
static void palette_undo_preserve(BlendLibReader *UNUSED(reader), ID *id_new, ID *id_old)
{
- /* Whole Palette is preserved accross undo's, and it has no extra pointer, simple. */
+ /* 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. */
/* Note: We do not swap IDProperties, as dealing with potential ID pointers in those would be
* fairly delicate. */
@@ -158,6 +158,8 @@ IDTypeInfo IDType_ID_PAL = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = palette_undo_preserve,
+
+ .lib_override_apply_post = NULL,
};
static void paint_curve_copy_data(Main *UNUSED(bmain),
@@ -221,6 +223,8 @@ IDTypeInfo IDType_ID_PC = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 335913c9b8e..21d1e070389 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -511,6 +511,8 @@ IDTypeInfo IDType_ID_PA = {
.blend_read_expand = particle_settings_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
@@ -2302,7 +2304,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd,
}
return;
}
- /* we cant use the num_dmcache */
+ /* we can't use the num_dmcache */
psys_particle_on_dm(
psmd->mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco);
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 55d4043f96c..c727a144c87 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1400,8 +1400,9 @@ void psys_update_particle_tree(ParticleSystem *psys, float cfra)
static void psys_update_effectors(ParticleSimulationData *sim)
{
BKE_effectors_free(sim->psys->effectors);
+ bool use_rotation = (sim->psys->part->flag & PART_ROT_DYN) != 0;
sim->psys->effectors = BKE_effectors_create(
- sim->depsgraph, sim->ob, sim->psys, sim->psys->part->effector_weights);
+ sim->depsgraph, sim->ob, sim->psys, sim->psys->part->effector_weights, use_rotation);
precalc_guides(sim, sim->psys->effectors);
}
diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc
index 7bd14e80333..b9ff2a1179d 100644
--- a/source/blender/blenkernel/intern/pointcloud.cc
+++ b/source/blender/blenkernel/intern/pointcloud.cc
@@ -190,6 +190,8 @@ IDTypeInfo IDType_ID_PT = {
/* blend_read_expand */ pointcloud_blend_read_expand,
/* blend_read_undo_preserve */ nullptr,
+
+ /* lib_override_apply_post */ nullptr,
};
static void pointcloud_random(PointCloud *pointcloud)
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 586aeb274a5..19078446009 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1720,7 +1720,7 @@ static void rigidbody_update_sim_ob(
ListBase *effectors;
/* get effectors present in the group specified by effector_weights */
- effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weights);
+ effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weights, false);
if (effectors) {
float eff_force[3] = {0.0f, 0.0f, 0.0f};
float eff_loc[3], eff_vel[3];
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index b19b0e684b2..25951fa3e6f 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -475,7 +475,7 @@ static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSE
/**
* This code is shared by both the regular `foreach_id` looper, and the code trying to restore or
- * preserve ID pointers like brushes across undoes.
+ * preserve ID pointers like brushes across undo-steps.
*/
typedef enum eSceneForeachUndoPreserveProcess {
/* Undo when preserving tool-settings from old scene, we also want to try to preserve that ID
@@ -1689,6 +1689,19 @@ 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))
+{
+ Scene *scene = (Scene *)id_dst;
+
+ if (scene->rigidbody_world != NULL) {
+ PTCacheID pid;
+ BKE_ptcache_id_from_rigidbody(&pid, NULL, scene->rigidbody_world);
+ LISTBASE_FOREACH (PointCache *, point_cache, pid.ptcaches) {
+ point_cache->flag |= PTCACHE_FLAG_INFO_DIRTY;
+ }
+ }
+}
+
IDTypeInfo IDType_ID_SCE = {
.id_code = ID_SCE,
.id_filter = FILTER_ID_SCE,
@@ -1714,6 +1727,8 @@ IDTypeInfo IDType_ID_SCE = {
.blend_read_expand = scene_blend_read_expand,
.blend_read_undo_preserve = scene_undo_preserve,
+
+ .lib_override_apply_post = scene_lib_override_apply_post,
};
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 52c41c9fd05..80a83aecea8 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -315,6 +315,8 @@ IDTypeInfo IDType_ID_SCR = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* ************ Spacetype/regiontype handling ************** */
@@ -1599,8 +1601,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
BLO_read_list(reader, &snode->treepath);
snode->edittree = NULL;
- snode->iofsd = NULL;
- BLI_listbase_clear(&snode->linkdrag);
+ snode->runtime = NULL;
}
else if (sl->spacetype == SPACE_TEXT) {
SpaceText *st = (SpaceText *)sl;
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index 14e6ce63023..4e0a08455e6 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -173,6 +173,8 @@ IDTypeInfo IDType_ID_SIM = {
/* blend_read_expand */ simulation_blend_read_expand,
/* blend_read_undo_preserve */ nullptr,
+
+ /* lib_override_apply_post */ nullptr,
};
void *BKE_simulation_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 736acd76dfd..de88e8a941c 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1539,7 +1539,8 @@ static void sb_sfesf_threads_run(struct Depsgraph *depsgraph,
* or even be UI option sb->spawn_cf_threads_nopts */
int lowsprings = 100;
- ListBase *effectors = BKE_effectors_create(depsgraph, ob, NULL, ob->soft->effector_weights);
+ ListBase *effectors = BKE_effectors_create(
+ depsgraph, ob, NULL, ob->soft->effector_weights, false);
/* figure the number of threads while preventing pretty pointless threading overhead */
totthread = BKE_scene_num_threads(scene);
@@ -2300,7 +2301,7 @@ static void softbody_calc_forces(
}
/* after spring scan because it uses Effoctors too */
- ListBase *effectors = BKE_effectors_create(depsgraph, ob, NULL, sb->effector_weights);
+ ListBase *effectors = BKE_effectors_create(depsgraph, ob, NULL, sb->effector_weights, false);
if (do_deflector) {
float defforce[3];
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 78729fb9261..0c917434bd1 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -221,6 +221,8 @@ IDTypeInfo IDType_ID_SO = {
.blend_read_expand = sound_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
#ifdef WITH_AUDASPACE
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index fabf0bb8971..9caeaf05e6a 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -114,6 +114,8 @@ IDTypeInfo IDType_ID_SPK = {
.blend_read_expand = speaker_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
void *BKE_speaker_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 9ef2e818293..9bf215515f7 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -258,6 +258,8 @@ IDTypeInfo IDType_ID_TXT = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/** \} */
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 4c2e4a82acb..ce84bfcd95a 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -226,6 +226,8 @@ IDTypeInfo IDType_ID_TE = {
.blend_read_expand = texture_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* Utils for all IDs using those texture slots. */
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index e5f9d59270e..d124922acd1 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -587,15 +587,15 @@ MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking,
{
const MovieTrackingSettings *settings = &tracking->settings;
+ MovieTrackingTrack *track = BKE_tracking_track_add_empty(tracking, tracksbase);
+ MovieTrackingMarker marker;
+
const float half_pattern_px = settings->default_pattern_size / 2.0f;
const float half_search_px = settings->default_search_size / 2.0f;
const float pattern_size[2] = {half_pattern_px / width, half_pattern_px / height};
const float search_size[2] = {half_search_px / width, half_search_px / height};
- MovieTrackingTrack *track = BKE_tracking_track_add_empty(tracking, tracksbase);
-
- MovieTrackingMarker marker;
memset(&marker, 0, sizeof(marker));
marker.pos[0] = x;
marker.pos[1] = y;
@@ -665,6 +665,86 @@ void BKE_tracking_track_free(MovieTrackingTrack *track)
}
}
+/* Get frame numbers of the very first and last markers.
+ * There is no check on whether the marker is enabled or not. */
+void BKE_tracking_track_first_last_frame_get(const MovieTrackingTrack *track,
+ int *r_first_frame,
+ int *r_last_frame)
+{
+ BLI_assert(track->markersnr > 0);
+ const int last_marker_index = track->markersnr - 1;
+ *r_first_frame = track->markers[0].framenr;
+ *r_last_frame = track->markers[last_marker_index].framenr;
+}
+
+/* Find the minimum starting frame and maximum ending frame within given set of
+ * tracks.
+ */
+void BKE_tracking_tracks_first_last_frame_minmax(/*const*/ MovieTrackingTrack **tracks,
+ const int num_tracks,
+ int *r_first_frame,
+ int *r_last_frame)
+{
+ *r_first_frame = INT_MAX;
+ *r_last_frame = INT_MIN;
+ for (int i = 0; i < num_tracks; ++i) {
+ const struct MovieTrackingTrack *track = tracks[i];
+ int track_first_frame, track_last_frame;
+ BKE_tracking_track_first_last_frame_get(track, &track_first_frame, &track_last_frame);
+ *r_first_frame = min_ii(*r_first_frame, track_first_frame);
+ *r_last_frame = max_ii(*r_last_frame, track_last_frame);
+ }
+}
+
+int BKE_tracking_count_selected_tracks_in_list(const ListBase *tracks_list)
+{
+ int num_selected_tracks = 0;
+ LISTBASE_FOREACH (const MovieTrackingTrack *, track, tracks_list) {
+ if (TRACK_SELECTED(track)) {
+ ++num_selected_tracks;
+ }
+ }
+ return num_selected_tracks;
+}
+
+int BKE_tracking_count_selected_tracks_in_active_object(/*const*/ MovieTracking *tracking)
+{
+ ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
+ return BKE_tracking_count_selected_tracks_in_list(tracks_list);
+}
+
+MovieTrackingTrack **BKE_tracking_selected_tracks_in_active_object(MovieTracking *tracking,
+ int *r_num_tracks)
+{
+ *r_num_tracks = 0;
+
+ ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
+ if (tracks_list == NULL) {
+ return NULL;
+ }
+
+ /* Initialize input. */
+ const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
+ if (num_selected_tracks == 0) {
+ return NULL;
+ }
+
+ MovieTrackingTrack **source_tracks = MEM_malloc_arrayN(
+ num_selected_tracks, sizeof(MovieTrackingTrack *), "selected tracks array");
+ int source_track_index = 0;
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks_list) {
+ if (!TRACK_SELECTED(track)) {
+ continue;
+ }
+ source_tracks[source_track_index] = track;
+ ++source_track_index;
+ }
+
+ *r_num_tracks = num_selected_tracks;
+
+ return source_tracks;
+}
+
/* Set flag for all specified track's areas.
*
* area - which part of marker should be selected. see TRACK_AREA_* constants.
@@ -918,6 +998,124 @@ void BKE_tracking_tracks_join(MovieTracking *tracking,
BKE_tracking_dopesheet_tag_update(tracking);
}
+static void accumulate_marker(MovieTrackingMarker *dst_marker,
+ const MovieTrackingMarker *src_marker)
+{
+ BLI_assert(dst_marker->framenr == src_marker->framenr);
+
+ if (src_marker->flag & MARKER_DISABLED) {
+ return;
+ }
+
+ add_v2_v2(dst_marker->pos, src_marker->pos);
+ for (int corner = 0; corner < 4; ++corner) {
+ add_v2_v2(dst_marker->pattern_corners[corner], src_marker->pattern_corners[corner]);
+ }
+ add_v2_v2(dst_marker->search_min, src_marker->search_min);
+ add_v2_v2(dst_marker->search_max, src_marker->search_max);
+
+ BLI_assert(is_finite_v2(src_marker->search_min));
+ BLI_assert(is_finite_v2(src_marker->search_max));
+
+ dst_marker->flag &= ~MARKER_DISABLED;
+ if ((src_marker->flag & MARKER_TRACKED) == 0) {
+ dst_marker->flag &= ~MARKER_TRACKED;
+ }
+}
+
+static void multiply_marker(MovieTrackingMarker *marker, const float multiplier)
+{
+ mul_v2_fl(marker->pos, multiplier);
+ for (int corner = 0; corner < 4; ++corner) {
+ mul_v2_fl(marker->pattern_corners[corner], multiplier);
+ }
+ mul_v2_fl(marker->search_min, multiplier);
+ mul_v2_fl(marker->search_max, multiplier);
+}
+
+/* Helper function for BKE_tracking_tracks_average which takes care of averaging fields of
+ * markers (position, patterns, ...). */
+static void tracking_average_markers(MovieTrackingTrack *dst_track,
+ /*const*/ MovieTrackingTrack **src_tracks,
+ const int num_src_tracks)
+{
+ /* Get global range of frames within which averaging would happen. */
+ int first_frame, last_frame;
+ BKE_tracking_tracks_first_last_frame_minmax(
+ src_tracks, num_src_tracks, &first_frame, &last_frame);
+ if (last_frame < first_frame) {
+ return;
+ }
+ const int num_frames = last_frame - first_frame + 1;
+
+ /* Allocate temporary array where averaging will happen into. */
+ MovieTrackingMarker *accumulator = MEM_calloc_arrayN(
+ num_frames, sizeof(MovieTrackingMarker), "tracks average accumulator");
+ int *counters = MEM_calloc_arrayN(num_frames, sizeof(int), "tracks accumulator counters");
+ for (int frame = first_frame; frame <= last_frame; ++frame) {
+ const int frame_index = frame - first_frame;
+ accumulator[frame_index].framenr = frame;
+ accumulator[frame_index].flag |= (MARKER_DISABLED | MARKER_TRACKED);
+ }
+
+ /* Accumulate track markers. */
+ for (int track_index = 0; track_index < num_src_tracks; ++track_index) {
+ /*const*/ MovieTrackingTrack *track = src_tracks[track_index];
+ for (int frame = first_frame; frame <= last_frame; ++frame) {
+ MovieTrackingMarker interpolated_marker;
+ if (!BKE_tracking_marker_get_interpolated(track, frame, &interpolated_marker)) {
+ continue;
+ }
+ const int frame_index = frame - first_frame;
+ accumulate_marker(&accumulator[frame_index], &interpolated_marker);
+ ++counters[frame_index];
+ }
+ }
+
+ /* Average and store the result. */
+ for (int frame = first_frame; frame <= last_frame; ++frame) {
+ /* Average. */
+ const int frame_index = frame - first_frame;
+ if (!counters[frame_index]) {
+ continue;
+ }
+ const float multiplier = 1.0f / (float)counters[frame_index];
+ multiply_marker(&accumulator[frame_index], multiplier);
+ /* Store the result. */
+ BKE_tracking_marker_insert(dst_track, &accumulator[frame_index]);
+ }
+
+ /* Free memory. */
+ MEM_freeN(accumulator);
+ MEM_freeN(counters);
+}
+
+/* Helper function for BKE_tracking_tracks_average which takes care of averaging fields of
+ * tracks (track for example, offset). */
+static void tracking_average_tracks(MovieTrackingTrack *dst_track,
+ /*const*/ MovieTrackingTrack **src_tracks,
+ const int num_src_tracks)
+{
+ /* TODO(sergey): Consider averaging weight, stabilization weight, maybe even bundle position. */
+ zero_v2(dst_track->offset);
+ for (int track_index = 0; track_index < num_src_tracks; track_index++) {
+ add_v2_v2(dst_track->offset, src_tracks[track_index]->offset);
+ }
+ mul_v2_fl(dst_track->offset, 1.0f / num_src_tracks);
+}
+
+void BKE_tracking_tracks_average(MovieTrackingTrack *dst_track,
+ /*const*/ MovieTrackingTrack **src_tracks,
+ const int num_src_tracks)
+{
+ if (num_src_tracks == 0) {
+ return;
+ }
+
+ tracking_average_markers(dst_track, src_tracks, num_src_tracks);
+ tracking_average_tracks(dst_track, src_tracks, num_src_tracks);
+}
+
MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking,
MovieTrackingObject *object,
const char *name)
@@ -1224,8 +1422,6 @@ MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track,
/* put new marker */
track->markers[a + 1] = *marker;
- track->last_marker = a + 1;
-
return &track->markers[a + 1];
}
@@ -1314,51 +1510,47 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
}
}
+/**
+ * Get marker closest to the given frame number.
+ *
+ * If there is maker with exact frame number it returned.
+ * Otherwise, marker with highest frame number but lower than the requested
+ * frame is returned if such marker exists. Otherwise, the marker with lowest
+ * frame number greater than the requested frame number is returned.
+ *
+ * This function has complexity of `O(log number_of_markers)`.
+ */
MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
{
- int a = track->markersnr - 1;
+ const int num_markers = track->markersnr;
- if (!track->markersnr) {
+ if (num_markers == 0) {
+ BLI_assert(!"Detected degenerated track, should never happen.");
return NULL;
}
- /* approximate pre-first framenr marker with first marker */
- if (framenr < track->markers[0].framenr) {
- return &track->markers[0];
- }
+ int left_boundary = 0;
+ int right_boundary = num_markers;
+ while (left_boundary < right_boundary) {
+ const int median_index = (left_boundary + right_boundary) / 2;
+ MovieTrackingMarker *marker = &track->markers[median_index];
- if (track->last_marker < track->markersnr) {
- a = track->last_marker;
- }
-
- if (track->markers[a].framenr <= framenr) {
- while (a < track->markersnr && track->markers[a].framenr <= framenr) {
- if (track->markers[a].framenr == framenr) {
- track->last_marker = a;
-
- return &track->markers[a];
- }
- a++;
+ if (marker->framenr == framenr) {
+ return marker;
}
- /* if there's no marker for exact position, use nearest marker from left side */
- return &track->markers[a - 1];
- }
-
- while (a >= 0 && track->markers[a].framenr >= framenr) {
- if (track->markers[a].framenr == framenr) {
- track->last_marker = a;
-
- return &track->markers[a];
+ if (marker->framenr < framenr) {
+ left_boundary = median_index + 1;
+ }
+ else {
+ BLI_assert(marker->framenr > framenr);
+ right_boundary = median_index - 1;
}
-
- a--;
}
- /* if there's no marker for exact position, use nearest marker from left side */
- return &track->markers[a];
+ const int closest_index = clamp_i(right_boundary, 0, num_markers - 1);
- return NULL;
+ return &track->markers[closest_index];
}
MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
@@ -1389,6 +1581,84 @@ MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int f
return marker;
}
+static const MovieTrackingMarker *get_usable_marker_for_interpolation(
+ struct MovieTrackingTrack *track,
+ const MovieTrackingMarker *anchor_marker,
+ const int direction)
+{
+ BLI_assert(direction == -1 || direction == 1);
+
+ const MovieTrackingMarker *last_marker = track->markers + track->markersnr - 1;
+ const MovieTrackingMarker *current_marker = anchor_marker;
+
+ while (current_marker >= track->markers && current_marker <= last_marker) {
+ if ((current_marker->flag & MARKER_DISABLED) == 0) {
+ return current_marker;
+ }
+ current_marker += direction;
+ }
+
+ return NULL;
+}
+
+bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track,
+ const int framenr,
+ struct MovieTrackingMarker *r_marker)
+{
+ const MovieTrackingMarker *closest_marker = BKE_tracking_marker_get(track, framenr);
+ if (closest_marker == NULL) {
+ return false;
+ }
+ if (closest_marker->framenr == framenr && (closest_marker->flag & MARKER_DISABLED) == 0) {
+ *r_marker = *closest_marker;
+ return true;
+ }
+
+ const MovieTrackingMarker *left_marker = get_usable_marker_for_interpolation(
+ track, closest_marker, -1);
+ if (left_marker == NULL) {
+ return false;
+ }
+
+ const MovieTrackingMarker *right_marker = get_usable_marker_for_interpolation(
+ track, closest_marker + 1, 1);
+ if (right_marker == NULL) {
+ return false;
+ }
+
+ if (left_marker == right_marker) {
+ *r_marker = *left_marker;
+ return true;
+ }
+
+ const float factor = (float)(framenr - left_marker->framenr) /
+ (right_marker->framenr - left_marker->framenr);
+
+ interp_v2_v2v2(r_marker->pos, left_marker->pos, right_marker->pos, factor);
+
+ for (int i = 0; i < 4; i++) {
+ interp_v2_v2v2(r_marker->pattern_corners[i],
+ left_marker->pattern_corners[i],
+ right_marker->pattern_corners[i],
+ factor);
+ }
+
+ interp_v2_v2v2(r_marker->search_min, left_marker->search_min, right_marker->search_min, factor);
+ interp_v2_v2v2(r_marker->search_max, left_marker->search_max, right_marker->search_max, factor);
+
+ r_marker->framenr = framenr;
+ r_marker->flag = 0;
+
+ if (framenr == left_marker->framenr) {
+ r_marker->flag = left_marker->flag;
+ }
+ else if (framenr == right_marker->framenr) {
+ r_marker->flag = right_marker->flag;
+ }
+
+ return true;
+}
+
void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker,
float min[2],
float max[2])
@@ -1683,7 +1953,6 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_insert(MovieTrackingPlaneTra
/* Put new marker to an array. */
plane_track->markers[a + 1] = *plane_marker;
- plane_track->last_marker = a + 1;
return &plane_track->markers[a + 1];
}
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index 6f58416924f..46589a578a8 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -311,11 +311,7 @@ static void retrieve_next_lower_usable_frame(
* translation stabilization, which has an enabled tracking marker at this very
* frame. We search both for the next lower and next higher position, to allow
* the caller to interpolate gaps and to extrapolate at the ends of the
- * definition range.
- *
- * NOTE: Regarding performance note that the individual tracks will cache the
- * last search position.
- */
+ * definition range. */
static void find_next_working_frames(StabContext *ctx,
int framenr,
int *next_lower,
diff --git a/source/blender/blenkernel/intern/tracking_test.cc b/source/blender/blenkernel/intern/tracking_test.cc
index 6afcf6872eb..a3845dcad8f 100644
--- a/source/blender/blenkernel/intern/tracking_test.cc
+++ b/source/blender/blenkernel/intern/tracking_test.cc
@@ -5,15 +5,23 @@
#include "DNA_tracking_types.h"
#include "BKE_tracking.h"
+#include "BLI_float2.hh"
+
+namespace blender {
namespace {
class TrackingTest : public ::testing::Test {
protected:
- MovieTrackingMarker *addMarkerToTrack(MovieTrackingTrack *track, int frame_number)
+ MovieTrackingMarker *addMarkerToTrack(MovieTrackingTrack *track,
+ int frame_number,
+ const float2 &position = float2(0.0f, 0.0f),
+ int flag = 0)
{
MovieTrackingMarker marker = {{0.0f}};
+ copy_v2_v2(marker.pos, position);
marker.framenr = frame_number;
+ marker.flag = flag;
return BKE_tracking_marker_insert(track, &marker);
}
};
@@ -22,24 +30,58 @@ class TrackingTest : public ::testing::Test {
TEST_F(TrackingTest, BKE_tracking_marker_get)
{
- MovieTrackingTrack track = {nullptr};
+ {
+ MovieTrackingTrack track = {nullptr};
- addMarkerToTrack(&track, 1);
- addMarkerToTrack(&track, 10);
+ addMarkerToTrack(&track, 10);
- {
- const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 1);
- EXPECT_NE(marker, nullptr);
- EXPECT_EQ(marker->framenr, 1);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 0), &track.markers[0]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 10), &track.markers[0]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 20), &track.markers[0]);
+
+ BKE_tracking_track_free(&track);
}
{
- const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 5);
- EXPECT_NE(marker, nullptr);
- EXPECT_EQ(marker->framenr, 1);
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1);
+ addMarkerToTrack(&track, 10);
+
+ {
+ const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 1);
+ EXPECT_NE(marker, nullptr);
+ EXPECT_EQ(marker->framenr, 1);
+ }
+
+ {
+ const MovieTrackingMarker *marker = BKE_tracking_marker_get(&track, 5);
+ EXPECT_NE(marker, nullptr);
+ EXPECT_EQ(marker->framenr, 1);
+ }
+
+ BKE_tracking_track_free(&track);
}
- BKE_tracking_track_free(&track);
+ {
+ {
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1);
+ addMarkerToTrack(&track, 2);
+ addMarkerToTrack(&track, 10);
+
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 0), &track.markers[0]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 1), &track.markers[0]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 2), &track.markers[1]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 3), &track.markers[1]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 9), &track.markers[1]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 10), &track.markers[2]);
+ EXPECT_EQ(BKE_tracking_marker_get(&track, 11), &track.markers[2]);
+
+ BKE_tracking_track_free(&track);
+ }
+ }
}
TEST_F(TrackingTest, BKE_tracking_marker_get_exact)
@@ -62,3 +104,107 @@ TEST_F(TrackingTest, BKE_tracking_marker_get_exact)
BKE_tracking_track_free(&track);
}
+
+TEST_F(TrackingTest, BKE_tracking_marker_get_interpolated)
+{
+ /* Simple case, no disabled markers in a way. */
+ {
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1, float2(1.0f, 5.0f));
+ addMarkerToTrack(&track, 10, float2(2.0f, 1.0f));
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 1);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.0f, 5.0f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 10);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(2.0f, 1.0f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 4);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.3333333f, 3.6666666f), 1e-6f);
+ }
+
+ BKE_tracking_track_free(&track);
+ }
+
+ /* More comprehensive test, which resembles real-life tracking scenario better. */
+ {
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1, float2(1.0f, 5.0f));
+ addMarkerToTrack(&track, 2, float2(0.0f, 0.0f), MARKER_DISABLED);
+ addMarkerToTrack(&track, 9, float2(0.0f, 0.0f), MARKER_DISABLED);
+ addMarkerToTrack(&track, 10, float2(2.0f, 1.0f));
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 1);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.0f, 5.0f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 10);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(2.0f, 1.0f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 4);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.3333333f, 3.6666666f), 1e-6f);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 9, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.framenr, 9);
+ EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.888888f, 1.4444444f), 1e-6f);
+ }
+
+ BKE_tracking_track_free(&track);
+ }
+
+ /* Tracked/keyframed flag check. */
+ {
+ MovieTrackingTrack track = {nullptr};
+
+ addMarkerToTrack(&track, 1, float2(1.0f, 5.0f), MARKER_TRACKED);
+ addMarkerToTrack(&track, 10, float2(2.0f, 1.0f), MARKER_TRACKED);
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.flag, MARKER_TRACKED);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.flag, MARKER_TRACKED);
+ }
+
+ {
+ MovieTrackingMarker interpolated_marker;
+ EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, &interpolated_marker));
+ EXPECT_EQ(interpolated_marker.flag, 0);
+ }
+
+ BKE_tracking_track_free(&track);
+ }
+}
+
+} // namespace blender
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index e78576206de..bb871e84c7b 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -176,8 +176,12 @@ static bool undosys_step_encode(bContext *C, Main *bmain, UndoStack *ustack, Und
return ok;
}
-static void undosys_step_decode(
- bContext *C, Main *bmain, UndoStack *ustack, UndoStep *us, int dir, bool is_final)
+static void undosys_step_decode(bContext *C,
+ Main *bmain,
+ UndoStack *ustack,
+ UndoStep *us,
+ const eUndoStepDir dir,
+ bool is_final)
{
CLOG_INFO(&LOG, 2, "addr=%p, name='%s', type='%s'", us, us->name, us->type->name);
@@ -251,42 +255,10 @@ static void undosys_stack_validate(UndoStack *ustack, bool expect_non_empty)
BLI_assert(!BLI_listbase_is_empty(&ustack->steps));
}
}
-
-/* Return whether `us_item` is before (-1), after (1) or same as (0) `us_anchor` step. */
-static int undosys_stack_order(const UndoStack *ustack,
- const UndoStep *us_anchor,
- const UndoStep *us_item)
-{
- const int index_anchor = BLI_findindex(&ustack->steps, us_anchor);
- const int index_item = BLI_findindex(&ustack->steps, us_item);
- BLI_assert(index_anchor >= 0);
- BLI_assert(index_item >= 0);
-
- return (index_item == index_anchor) ? 0 : (index_item < index_anchor) ? -1 : 1;
-}
-
-# define ASSERT_VALID_UNDO_STEP(_ustack, _us_undo) \
- { \
- const UndoStep *_us_anchor = (_ustack)->step_active; \
- BLI_assert(_us_anchor == NULL || \
- (undosys_stack_order((_ustack), _us_anchor, (_us_undo)) <= 0)); \
- } \
- (void)0
-
-# define ASSERT_VALID_REDO_STEP(_ustack, _us_redo) \
- { \
- const UndoStep *_us_anchor = (_ustack)->step_active; \
- BLI_assert(_us_anchor == NULL || \
- (undosys_stack_order((_ustack), _us_anchor, (_us_redo)) >= 0)); \
- } \
- (void)0
-
#else
static void undosys_stack_validate(UndoStack *UNUSED(ustack), bool UNUSED(expect_non_empty))
{
}
-# define ASSERT_VALID_UNDO_STEP(_ustack, _us_undo)
-# define ASSERT_VALID_REDO_STEP(_ustack, _us_redo)
#endif
UndoStack *BKE_undosys_stack_create(void)
@@ -315,7 +287,7 @@ void BKE_undosys_stack_clear(UndoStack *ustack)
void BKE_undosys_stack_clear_active(UndoStack *ustack)
{
- /* Remove active and all following undos. */
+ /* Remove active and all following undo-steps. */
UndoStep *us = ustack->step_active;
if (us) {
@@ -545,7 +517,7 @@ UndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack,
retval |= UNDO_PUSH_RET_OVERRIDE_CHANGED;
}
- /* Remove all undos after (also when 'ustack->step_active == NULL'). */
+ /* Remove all undo-steps after (also when 'ustack->step_active == NULL'). */
while (ustack->steps.last != ustack->step_active) {
UndoStep *us_iter = ustack->steps.last;
undosys_step_free_and_unlink(ustack, us_iter);
@@ -586,7 +558,7 @@ UndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack,
BLI_strncpy(us->name, name, sizeof(us->name));
}
us->type = ut;
- /* True by default, code needs to explicitely set it to false if necessary. */
+ /* True by default, code needs to explicitly set it to false if necessary. */
us->use_old_bmain_data = true;
/* Initialized, not added yet. */
@@ -701,37 +673,91 @@ UndoStep *BKE_undosys_step_find_by_type(UndoStack *ustack, const UndoType *ut)
return NULL;
}
-bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
- bContext *C,
- UndoStep *us,
- bool use_skip)
+/**
+ * Return direction of the undo/redo from `us_reference` (or `ustack->step_active` if NULL), and
+ * `us_target`.
+ *
+ * \note If `us_reference` and `us_target` are the same, we consider this is an undo.
+ *
+ * \return -1 for undo, 1 for redo, 0 in case of error.
+ */
+eUndoStepDir BKE_undosys_step_calc_direction(const UndoStack *ustack,
+ const UndoStep *us_target,
+ const UndoStep *us_reference)
+{
+ if (us_reference == NULL) {
+ us_reference = ustack->step_active;
+ }
+
+ BLI_assert(us_reference != NULL);
+
+ /* Note that we use heuristics to make this lookup as fast as possible in most common cases,
+ * assuming that:
+ * - Most cases are just undo or redo of one step from active one.
+ * - Otherwise, it is typically faster to check future steps since active one is usually close
+ * to the end of the list, rather than its start. */
+ /* NOTE: in case target step is the active one, we assume we are in an undo case... */
+ if (ELEM(us_target, us_reference, us_reference->prev)) {
+ return STEP_UNDO;
+ }
+ if (us_target == us_reference->next) {
+ return STEP_REDO;
+ }
+
+ /* Search forward, and then backward. */
+ for (UndoStep *us_iter = us_reference->next; us_iter != NULL; us_iter = us_iter->next) {
+ if (us_iter == us_target) {
+ return STEP_REDO;
+ }
+ }
+ for (UndoStep *us_iter = us_reference->prev; us_iter != NULL; us_iter = us_iter->prev) {
+ if (us_iter == us_target) {
+ return STEP_UNDO;
+ }
+ }
+
+ BLI_assert(!"Target undo step not found, this should not happen and may indicate an undo stack corruption");
+ return STEP_INVALID;
+}
+
+/**
+ * Undo/Redo until the given `us_target` step becomes the active (currently loaded) one.
+ *
+ * \note Unless `us_target` is a 'skipped' one and `use_skip` is true, `us_target` will become the
+ * active step.
+ *
+ * \note In case `use_skip` is true, the final target will always be **beyond** the given one (if
+ * the given one has to be skipped).
+ *
+ * \param us_reference If NULL, will be set to current active step in the undo stack. Otherwise, it
+ * is assumed to match the current state, and will be used as basis for the
+ * undo/redo process (i.e. all steps in-between `us_reference` and `us_target`
+ * will be processed).
+ */
+bool BKE_undosys_step_load_data_ex(UndoStack *ustack,
+ bContext *C,
+ UndoStep *us_target,
+ UndoStep *us_reference,
+ const bool use_skip)
{
UNDO_NESTED_ASSERT(false);
- if (us == NULL) {
- CLOG_ERROR(&LOG, "called with a NULL step");
+ if (us_target == NULL) {
+ CLOG_ERROR(&LOG, "called with a NULL target step");
return false;
}
undosys_stack_validate(ustack, true);
- /* We expect to get next-from-actual-target step here (i.e. active step in case we only undo
- * once)?
- * FIXME: this is very confusing now that we may have to undo several steps anyway, this function
- * should just get the target final step, not assume that it is getting the active one by default
- * (or the step after the target one when undoing more than one step). */
- UndoStep *us_target = us->prev;
- if (us_target == NULL) {
- CLOG_ERROR(&LOG, "could not find a valid target step");
+ if (us_reference == NULL) {
+ us_reference = ustack->step_active;
+ }
+ if (us_reference == NULL) {
+ CLOG_ERROR(&LOG, "could not find a valid initial active target step as reference");
return false;
}
- ASSERT_VALID_UNDO_STEP(ustack, us_target);
- /* This will be active once complete. */
- UndoStep *us_active = us_target;
- if (use_skip) {
- while (us_active && us_active->skip) {
- us_active = us_active->prev;
- }
- }
+ /* This considers we are in undo case if both `us_target` and `us_reference` are the same. */
+ const eUndoStepDir undo_dir = BKE_undosys_step_calc_direction(ustack, us_target, us_reference);
+ BLI_assert(undo_dir != STEP_INVALID);
/* This will be the active step once the undo process is complete.
*
@@ -740,7 +766,7 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
UndoStep *us_target_active = us_target;
if (use_skip) {
while (us_target_active != NULL && us_target_active->skip) {
- us_target_active = us_target_active->prev;
+ us_target_active = (undo_dir == -1) ? us_target_active->prev : us_target_active->next;
}
}
if (us_target_active == NULL) {
@@ -748,42 +774,47 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
return false;
}
- CLOG_INFO(
- &LOG, 1, "addr=%p, name='%s', type='%s'", us_target, us_target->name, us_target->type->name);
+ CLOG_INFO(&LOG,
+ 1,
+ "addr=%p, name='%s', type='%s', undo_dir=%d",
+ us_target,
+ us_target->name,
+ us_target->type->name,
+ undo_dir);
- /* Undo steps until we reach original given target, if we do have a current active step.
+ /* Undo/Redo steps until we reach given target step (or beyond if it has to be skipped), from
+ * given reference step.
*
* NOTE: Unlike with redo case, where we can expect current active step to fully reflect current
* data status, in undo case we also do reload the active step.
* FIXME: this feels weak, and should probably not be actually needed? Or should also be done in
* redo case? */
- if (ustack->step_active != NULL) {
- for (UndoStep *us_iter = ustack->step_active; us_iter != us_target; us_iter = us_iter->prev) {
- BLI_assert(us_iter != NULL);
- undosys_step_decode(C, G_MAIN, ustack, us_iter, -1, false);
- ustack->step_active = us_iter;
- }
- }
+ bool is_processing_extra_skipped_steps = false;
+ for (UndoStep *us_iter = (undo_dir == -1) ? us_reference : us_reference->next; us_iter != NULL;
+ us_iter = (undo_dir == -1) ? us_iter->prev : us_iter->next) {
+ BLI_assert(us_iter != NULL);
- /* Undo target step, and all potential extra ones if some steps have to be 'skipped'. */
- for (UndoStep *us_iter = us_target; us_iter != NULL; us_iter = us_iter->prev) {
const bool is_final = (us_iter == us_target_active);
- if (!is_final) {
+ if (!is_final && is_processing_extra_skipped_steps) {
BLI_assert(us_iter->skip == true);
CLOG_INFO(&LOG,
2,
- "undo continue with skip addr=%p, name='%s', type='%s'",
+ "undo/redo continue with skip addr=%p, name='%s', type='%s'",
us_iter,
us_iter->name,
us_iter->type->name);
}
- undosys_step_decode(C, G_MAIN, ustack, us_iter, -1, is_final);
+ undosys_step_decode(C, G_MAIN, ustack, us_iter, undo_dir, is_final);
ustack->step_active = us_iter;
+ if (us_iter == us_target) {
+ is_processing_extra_skipped_steps = true;
+ }
+
if (is_final) {
- /* Undo process is finished and successful. */
+ /* Undo/Redo process is finished and successful. */
return true;
}
}
@@ -793,139 +824,117 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
return false;
}
-bool BKE_undosys_step_undo_with_data(UndoStack *ustack, bContext *C, UndoStep *us)
-{
- return BKE_undosys_step_undo_with_data_ex(ustack, C, us, true);
-}
-
-bool BKE_undosys_step_undo(UndoStack *ustack, bContext *C)
+/**
+ * Undo/Redo until the given `us_target` step becomes the active (currently loaded) one.
+ */
+bool BKE_undosys_step_load_data(UndoStack *ustack, bContext *C, UndoStep *us_target)
{
- return BKE_undosys_step_undo_with_data(ustack, C, ustack->step_active);
+ /* Note that here we do not skip 'skipped' steps by default. */
+ return BKE_undosys_step_load_data_ex(ustack, C, us_target, NULL, false);
}
-void BKE_undosys_step_undo_from_index(UndoStack *ustack, bContext *C, int index)
+/**
+ * Undo/Redo until the step matching given `index` in the undo stack becomes the active (currently
+ * loaded) one.
+ */
+void BKE_undosys_step_load_from_index(UndoStack *ustack, bContext *C, const int index)
{
- UndoStep *us = BLI_findlink(&ustack->steps, index);
- BLI_assert(us->skip == false);
- BKE_undosys_step_load_data(ustack, C, us);
+ UndoStep *us_target = BLI_findlink(&ustack->steps, index);
+ BLI_assert(us_target->skip == false);
+ BKE_undosys_step_load_data(ustack, C, us_target);
}
-bool BKE_undosys_step_redo_with_data_ex(UndoStack *ustack,
+/**
+ * Undo until `us_target` step becomes the active (currently loaded) one.
+ *
+ * \warning This function assumes that the given target step is _before_ current active one.
+ *
+ * \note Unless `us_target` is a 'skipped' one and `use_skip` is true, `us_target` will become the
+ * active step.
+ *
+ * \note In case `use_skip` is true, the final target will always be **before** the given one (if
+ * the given one has to be skipped).
+ */
+bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
bContext *C,
- UndoStep *us,
+ UndoStep *us_target,
bool use_skip)
{
- UNDO_NESTED_ASSERT(false);
- if (us == NULL) {
- CLOG_ERROR(&LOG, "called with a NULL step");
- return false;
- }
- undosys_stack_validate(ustack, true);
+ /* In case there is no active step, we consider we just load given step, so reference must be
+ * itself (due to weird 'load current active step in undo case' thing, see comments in
+ * #BKE_undosys_step_load_data_ex). */
+ UndoStep *us_reference = ustack->step_active != NULL ? ustack->step_active : us_target;
- /* We expect to get previous-from-actual-target step here (i.e. active step in case we only redo
- * once)?
- * FIXME: this is very confusing now that we may have to redo several steps anyway, this function
- * should just get the target final step, not assume that it is getting the active one by default
- * (or the step before the target one when redoing more than one step). */
- UndoStep *us_target = us->next;
- if (us_target == NULL) {
- CLOG_ERROR(&LOG, "could not find a valid target step");
- return false;
- }
- ASSERT_VALID_REDO_STEP(ustack, us_target);
+ BLI_assert(BKE_undosys_step_calc_direction(ustack, us_target, us_reference) == -1);
- /* This will be the active step once the redo process is complete.
- *
- * In case we do skip 'skipped' steps, the final active step may be several steps forward the one
- * passed as parameter. */
- UndoStep *us_target_active = us_target;
- if (use_skip) {
- while (us_target_active != NULL && us_target_active->skip) {
- us_target_active = us_target_active->next;
- }
- }
- if (us_target_active == NULL) {
- CLOG_ERROR(&LOG, "could not find a valid final active target step");
- return false;
- }
+ return BKE_undosys_step_load_data_ex(ustack, C, us_target, us_reference, use_skip);
+}
- CLOG_INFO(
- &LOG, 1, "addr=%p, name='%s', type='%s'", us_target, us_target->name, us_target->type->name);
+/**
+ * Undo until `us_target` step becomes the active (currently loaded) one.
+ *
+ * \note See #BKE_undosys_step_undo_with_data_ex for details.
+ */
+bool BKE_undosys_step_undo_with_data(UndoStack *ustack, bContext *C, UndoStep *us_target)
+{
+ return BKE_undosys_step_undo_with_data_ex(ustack, C, us_target, true);
+}
- /* Redo steps until we reach original given target, if we do have a current active step. */
+/**
+ * Undo one step from current active (currently loaded) one.
+ */
+bool BKE_undosys_step_undo(UndoStack *ustack, bContext *C)
+{
if (ustack->step_active != NULL) {
- for (UndoStep *us_iter = ustack->step_active->next; us_iter != us_target;
- us_iter = us_iter->next) {
- BLI_assert(us_iter != NULL);
- undosys_step_decode(C, G_MAIN, ustack, us_iter, 1, false);
- ustack->step_active = us_iter;
- }
+ return BKE_undosys_step_undo_with_data(ustack, C, ustack->step_active->prev);
}
-
- /* Redo target step, and all potential extra ones if some steps have to be 'skipped'. */
- for (UndoStep *us_iter = us_target; us_iter != NULL; us_iter = us_iter->next) {
- const bool is_final = (us_iter == us_target_active);
-
- if (!is_final) {
- BLI_assert(us_iter->skip == true);
- CLOG_INFO(&LOG,
- 2,
- "redo continue with skip addr=%p, name='%s', type='%s'",
- us_iter,
- us_iter->name,
- us_iter->type->name);
- }
-
- undosys_step_decode(C, G_MAIN, ustack, us_iter, 1, is_final);
- ustack->step_active = us_iter;
-
- if (is_final) {
- /* Redo process is finished and successful. */
- return true;
- }
- }
-
- BLI_assert(
- !"This should never be reached, either undo stack is corrupted, or code above is buggy");
return false;
}
-bool BKE_undosys_step_redo_with_data(UndoStack *ustack, bContext *C, UndoStep *us)
+/**
+ * Redo until `us_target` step becomes the active (currently loaded) one.
+ *
+ * \warning This function assumes that the given target step is _after_ current active one.
+ *
+ * \note Unless `us_target` is a 'skipped' one and `use_skip` is true, `us_target` will become the
+ * active step.
+ *
+ * \note In case `use_skip` is true, the final target will always be **after** the given one (if
+ * the given one has to be skipped).
+ */
+bool BKE_undosys_step_redo_with_data_ex(UndoStack *ustack,
+ bContext *C,
+ UndoStep *us_target,
+ bool use_skip)
{
- return BKE_undosys_step_redo_with_data_ex(ustack, C, us, true);
+ /* In case there is no active step, we consider we just load given step, so reference must be
+ * the previous one. */
+ UndoStep *us_reference = ustack->step_active != NULL ? ustack->step_active : us_target->prev;
+
+ BLI_assert(BKE_undosys_step_calc_direction(ustack, us_target, us_reference) == 1);
+
+ return BKE_undosys_step_load_data_ex(ustack, C, us_target, us_reference, use_skip);
}
-bool BKE_undosys_step_redo(UndoStack *ustack, bContext *C)
+/**
+ * Redo until `us_target` step becomes the active (currently loaded) one.
+ *
+ * \note See #BKE_undosys_step_redo_with_data_ex for details.
+ */
+bool BKE_undosys_step_redo_with_data(UndoStack *ustack, bContext *C, UndoStep *us_target)
{
- return BKE_undosys_step_redo_with_data(ustack, C, ustack->step_active);
+ return BKE_undosys_step_redo_with_data_ex(ustack, C, us_target, true);
}
-bool BKE_undosys_step_load_data(UndoStack *ustack, bContext *C, UndoStep *us)
+/**
+ * Redo one step from current active one.
+ */
+bool BKE_undosys_step_redo(UndoStack *ustack, bContext *C)
{
- UNDO_NESTED_ASSERT(false);
- const int index_active = BLI_findindex(&ustack->steps, ustack->step_active);
- const int index_target = BLI_findindex(&ustack->steps, us);
- BLI_assert(!ELEM(-1, index_active, index_target));
- bool ok = true;
-
- if (index_target < index_active) {
- uint i = index_active - index_target;
- while (i-- && ok) {
- ok = BKE_undosys_step_undo_with_data_ex(ustack, C, ustack->step_active, false);
- }
- }
- else if (index_target > index_active) {
- uint i = index_target - index_active;
- while (i-- && ok) {
- ok = BKE_undosys_step_redo_with_data_ex(ustack, C, ustack->step_active, false);
- }
- }
-
- if (ok) {
- BLI_assert(ustack->step_active == us);
+ if (ustack->step_active != NULL) {
+ return BKE_undosys_step_redo_with_data(ustack, C, ustack->step_active->next);
}
-
- return ok;
+ return false;
}
/**
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index b55f80c6473..e98fae9d92a 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -1167,8 +1167,7 @@ bool BKE_unit_replace_string(
/* Replace # with add sign when there is no operator between it and the next number.
*
* "1*1# 3*100# * 3" -> "1*1+ 3*100 * 3"
- *
- * */
+ */
{
char *str_found = str;
const char *ch = str;
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 9e7a3736141..edf40ab3861 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -128,7 +128,7 @@ static struct VolumeFileCache {
std::lock_guard<std::mutex> lock(mutex);
return simplified_grids.lookup_or_add_cb(simplify_level, [&]() {
const float resolution_factor = 1.0f / (1 << simplify_level);
- const VolumeGridType grid_type = BKE_volume_grid_type_openvdb(grid);
+ const VolumeGridType grid_type = BKE_volume_grid_type_openvdb(*grid);
return BKE_volume_grid_create_with_changed_resolution(grid_type, *grid, resolution_factor);
});
}
@@ -145,7 +145,7 @@ static struct VolumeFileCache {
/* Has the grid tree been loaded? */
bool is_loaded;
- /* Error message if an error occured during loading. */
+ /* Error message if an error occurred while loading. */
std::string error_msg;
/* User counting. */
int num_metadata_users;
@@ -523,6 +523,8 @@ static void volume_copy_data(Main *UNUSED(bmain),
volume_dst->runtime.grids = OBJECT_GUARDED_NEW(VolumeGridVector, grids_src);
}
#endif
+
+ volume_dst->batch_cache = nullptr;
}
static void volume_free_data(ID *id)
@@ -642,6 +644,8 @@ IDTypeInfo IDType_ID_VO = {
/* blend_read_expand */ volume_blend_read_expand,
/* blend_read_undo_preserve */ nullptr,
+
+ /* lib_override_apply_post */ nullptr,
};
void BKE_volume_init_grids(Volume *volume)
@@ -1233,39 +1237,39 @@ const char *BKE_volume_grid_name(const VolumeGrid *volume_grid)
}
#ifdef WITH_OPENVDB
-VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase::Ptr &grid)
+VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase &grid)
{
- if (grid->isType<openvdb::FloatGrid>()) {
+ if (grid.isType<openvdb::FloatGrid>()) {
return VOLUME_GRID_FLOAT;
}
- if (grid->isType<openvdb::Vec3fGrid>()) {
+ if (grid.isType<openvdb::Vec3fGrid>()) {
return VOLUME_GRID_VECTOR_FLOAT;
}
- if (grid->isType<openvdb::BoolGrid>()) {
+ if (grid.isType<openvdb::BoolGrid>()) {
return VOLUME_GRID_BOOLEAN;
}
- if (grid->isType<openvdb::DoubleGrid>()) {
+ if (grid.isType<openvdb::DoubleGrid>()) {
return VOLUME_GRID_DOUBLE;
}
- if (grid->isType<openvdb::Int32Grid>()) {
+ if (grid.isType<openvdb::Int32Grid>()) {
return VOLUME_GRID_INT;
}
- if (grid->isType<openvdb::Int64Grid>()) {
+ if (grid.isType<openvdb::Int64Grid>()) {
return VOLUME_GRID_INT64;
}
- if (grid->isType<openvdb::Vec3IGrid>()) {
+ if (grid.isType<openvdb::Vec3IGrid>()) {
return VOLUME_GRID_VECTOR_INT;
}
- if (grid->isType<openvdb::Vec3dGrid>()) {
+ if (grid.isType<openvdb::Vec3dGrid>()) {
return VOLUME_GRID_VECTOR_DOUBLE;
}
- if (grid->isType<openvdb::StringGrid>()) {
+ if (grid.isType<openvdb::StringGrid>()) {
return VOLUME_GRID_STRING;
}
- if (grid->isType<openvdb::MaskGrid>()) {
+ if (grid.isType<openvdb::MaskGrid>()) {
return VOLUME_GRID_MASK;
}
- if (grid->isType<openvdb::points::PointDataGrid>()) {
+ if (grid.isType<openvdb::points::PointDataGrid>()) {
return VOLUME_GRID_POINTS;
}
return VOLUME_GRID_UNKNOWN;
@@ -1276,7 +1280,7 @@ VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid)
{
#ifdef WITH_OPENVDB
const openvdb::GridBase::Ptr grid = volume_grid->grid();
- return BKE_volume_grid_type_openvdb(grid);
+ return BKE_volume_grid_type_openvdb(*grid);
#else
UNUSED_VARS(volume_grid);
#endif
diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc
new file mode 100644
index 00000000000..7ab67516242
--- /dev/null
+++ b/source/blender/blenkernel/intern/volume_to_mesh.cc
@@ -0,0 +1,183 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <vector>
+
+#include "BLI_float3.hh"
+#include "BLI_span.hh"
+#include "BLI_utildefines.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_volume_types.h"
+
+#include "BKE_mesh.h"
+#include "BKE_volume.h"
+
+#ifdef WITH_OPENVDB
+# include <openvdb/tools/GridTransformer.h>
+# include <openvdb/tools/VolumeToMesh.h>
+#endif
+
+#include "BKE_volume_to_mesh.hh"
+
+namespace blender::bke {
+
+#ifdef WITH_OPENVDB
+
+struct VolumeToMeshOp {
+ const openvdb::GridBase &base_grid;
+ const VolumeToMeshResolution resolution;
+ const float threshold;
+ const float adaptivity;
+ std::vector<openvdb::Vec3s> verts;
+ std::vector<openvdb::Vec3I> tris;
+ std::vector<openvdb::Vec4I> quads;
+
+ template<typename GridType> bool operator()()
+ {
+ if constexpr (std::is_scalar_v<typename GridType::ValueType>) {
+ this->generate_mesh_data<GridType>();
+ return true;
+ }
+ return false;
+ }
+
+ template<typename GridType> void generate_mesh_data()
+ {
+ const GridType &grid = static_cast<const GridType &>(base_grid);
+
+ if (this->resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_GRID) {
+ this->grid_to_mesh(grid);
+ return;
+ }
+
+ const float resolution_factor = this->compute_resolution_factor(base_grid);
+ typename GridType::Ptr temp_grid = this->create_grid_with_changed_resolution(
+ grid, resolution_factor);
+ this->grid_to_mesh(*temp_grid);
+ }
+
+ template<typename GridType>
+ typename GridType::Ptr create_grid_with_changed_resolution(const GridType &old_grid,
+ const float resolution_factor)
+ {
+ BLI_assert(resolution_factor > 0.0f);
+
+ openvdb::Mat4R xform;
+ xform.setToScale(openvdb::Vec3d(resolution_factor));
+ openvdb::tools::GridTransformer transformer{xform};
+
+ typename GridType::Ptr new_grid = GridType::create();
+ transformer.transformGrid<openvdb::tools::BoxSampler>(old_grid, *new_grid);
+ new_grid->transform() = old_grid.transform();
+ new_grid->transform().preScale(1.0f / resolution_factor);
+ return new_grid;
+ }
+
+ float compute_resolution_factor(const openvdb::GridBase &grid) const
+ {
+ const openvdb::Vec3s voxel_size{grid.voxelSize()};
+ const float current_voxel_size = std::max({voxel_size[0], voxel_size[1], voxel_size[2]});
+ const float desired_voxel_size = this->compute_desired_voxel_size(grid);
+ return current_voxel_size / desired_voxel_size;
+ }
+
+ float compute_desired_voxel_size(const openvdb::GridBase &grid) const
+ {
+ if (this->resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
+ return this->resolution.settings.voxel_size;
+ }
+ const openvdb::CoordBBox coord_bbox = base_grid.evalActiveVoxelBoundingBox();
+ const openvdb::BBoxd bbox = grid.transform().indexToWorld(coord_bbox);
+ const float max_extent = bbox.extents()[bbox.maxExtent()];
+ const float voxel_size = max_extent / this->resolution.settings.voxel_amount;
+ return voxel_size;
+ }
+
+ template<typename GridType> void grid_to_mesh(const GridType &grid)
+ {
+ openvdb::tools::volumeToMesh(
+ grid, this->verts, this->tris, this->quads, this->threshold, this->adaptivity);
+
+ /* Better align generated mesh with volume (see T85312). */
+ openvdb::Vec3s offset = grid.voxelSize() / 2.0f;
+ for (openvdb::Vec3s &position : this->verts) {
+ position += offset;
+ }
+ }
+};
+
+static Mesh *new_mesh_from_openvdb_data(Span<openvdb::Vec3s> verts,
+ Span<openvdb::Vec3I> tris,
+ Span<openvdb::Vec4I> quads)
+{
+ const int tot_loops = 3 * tris.size() + 4 * quads.size();
+ const int tot_polys = tris.size() + quads.size();
+
+ Mesh *mesh = BKE_mesh_new_nomain(verts.size(), 0, 0, tot_loops, tot_polys);
+
+ /* Write vertices. */
+ for (const int i : verts.index_range()) {
+ const blender::float3 co = blender::float3(verts[i].asV());
+ copy_v3_v3(mesh->mvert[i].co, co);
+ }
+
+ /* Write triangles. */
+ for (const int i : tris.index_range()) {
+ mesh->mpoly[i].loopstart = 3 * i;
+ mesh->mpoly[i].totloop = 3;
+ for (int j = 0; j < 3; j++) {
+ /* Reverse vertex order to get correct normals. */
+ mesh->mloop[3 * i + j].v = tris[i][2 - j];
+ }
+ }
+
+ /* Write quads. */
+ const int poly_offset = tris.size();
+ const int loop_offset = tris.size() * 3;
+ for (const int i : quads.index_range()) {
+ mesh->mpoly[poly_offset + i].loopstart = loop_offset + 4 * i;
+ mesh->mpoly[poly_offset + i].totloop = 4;
+ for (int j = 0; j < 4; j++) {
+ /* Reverse vertex order to get correct normals. */
+ mesh->mloop[loop_offset + 4 * i + j].v = quads[i][3 - j];
+ }
+ }
+
+ BKE_mesh_calc_edges(mesh, false, false);
+ BKE_mesh_calc_normals(mesh);
+ return mesh;
+}
+
+Mesh *volume_to_mesh(const openvdb::GridBase &grid,
+ const VolumeToMeshResolution &resolution,
+ const float threshold,
+ const float adaptivity)
+{
+ const VolumeGridType grid_type = BKE_volume_grid_type_openvdb(grid);
+
+ VolumeToMeshOp to_mesh_op{grid, resolution, threshold, adaptivity};
+ if (!BKE_volume_grid_type_operation(grid_type, to_mesh_op)) {
+ return nullptr;
+ }
+
+ return new_mesh_from_openvdb_data(to_mesh_op.verts, to_mesh_op.tris, to_mesh_op.quads);
+}
+
+#endif /* WITH_OPENVDB */
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 291116556c3..5a101cf009b 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -192,6 +192,8 @@ IDTypeInfo IDType_ID_WS = {
.blend_read_expand = workspace_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 8fe7653fc25..a2ce37a5d90 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -206,6 +206,8 @@ IDTypeInfo IDType_ID_WO = {
.blend_read_expand = world_blend_read_expand,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
World *BKE_world_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h
index 7257be66b79..79c16e321be 100644
--- a/source/blender/blenkernel/nla_private.h
+++ b/source/blender/blenkernel/nla_private.h
@@ -106,14 +106,10 @@ typedef struct NlaEvalChannel {
int index;
bool is_array;
- bool in_blend;
char mix_mode;
- struct NlaEvalChannel *next_blend;
- NlaEvalChannelSnapshot *blend_snapshot;
-
- /* Mask of array items controlled by NLA. */
- NlaValidMask valid;
+ /* Associated with the RNA property's value(s), marks which elements are affected by NLA. */
+ NlaValidMask domain;
/* Base set of values. */
NlaEvalChannelSnapshot base_snapshot;
@@ -186,6 +182,15 @@ void nladata_flush_channels(PointerRNA *ptr,
NlaEvalSnapshot *snapshot,
const bool flush_to_original);
+void nlasnapshot_ensure_channels(NlaEvalData *eval_data, NlaEvalSnapshot *snapshot);
+
+void nlasnapshot_blend(NlaEvalData *eval_data,
+ NlaEvalSnapshot *lower_snapshot,
+ NlaEvalSnapshot *upper_snapshot,
+ const short upper_blendmode,
+ const float upper_influence,
+ NlaEvalSnapshot *r_blended_snapshot);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index c8e7fea6601..35c5221efa3 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -125,7 +125,7 @@ float *tracking_track_get_mask_for_region(int frame_width,
const float region_max[2],
MovieTrackingTrack *track);
-/*********************** Frame accessr *************************/
+/*********************** Frame Accessor *************************/
struct libmv_FrameAccessor;
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 74a491898b6..df80e720363 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -20,7 +20,7 @@
/** \file
* \ingroup bli
* \brief File and directory operations.
- * */
+ */
#pragma once
@@ -88,10 +88,10 @@ typedef enum eFileAttributes {
FILE_ATTR_TEMPORARY = 1 << 7, /* Used for temporary storage. */
FILE_ATTR_SPARSE_FILE = 1 << 8, /* Sparse File. */
FILE_ATTR_OFFLINE = 1 << 9, /* Data is not immediately available. */
- FILE_ATTR_ALIAS = 1 << 10, /* Mac Alias or Windows Lnk. File-based redirection. */
- FILE_ATTR_REPARSE_POINT = 1 << 11, /* File has associated reparse point. */
+ FILE_ATTR_ALIAS = 1 << 10, /* Mac Alias or Windows LNK. File-based redirection. */
+ FILE_ATTR_REPARSE_POINT = 1 << 11, /* File has associated re-parse point. */
FILE_ATTR_SYMLINK = 1 << 12, /* Reference to another file. */
- FILE_ATTR_JUNCTION_POINT = 1 << 13, /* Folder Symlink. */
+ FILE_ATTR_JUNCTION_POINT = 1 << 13, /* Folder Symbolic-link. */
FILE_ATTR_MOUNT_POINT = 1 << 14, /* Volume mounted as a folder. */
FILE_ATTR_HARDLINK = 1 << 15, /* Duplicated directory entry. */
} eFileAttributes;
diff --git a/source/blender/blenlib/BLI_float2.hh b/source/blender/blenlib/BLI_float2.hh
index 2a5320e4c35..84dd0e358a2 100644
--- a/source/blender/blenlib/BLI_float2.hh
+++ b/source/blender/blenlib/BLI_float2.hh
@@ -29,6 +29,14 @@ struct float2 {
{
}
+ explicit float2(float value) : x(value), y(value)
+ {
+ }
+
+ explicit float2(int value) : x(value), y(value)
+ {
+ }
+
float2(float x, float y) : x(x), y(y)
{
}
@@ -52,6 +60,11 @@ struct float2 {
return len_v2(*this);
}
+ float length_squared() const
+ {
+ return len_squared_v2(*this);
+ }
+
float2 &operator+=(const float2 &other)
{
x += other.x;
diff --git a/source/blender/blenlib/BLI_fnmatch.h b/source/blender/blenlib/BLI_fnmatch.h
index d09a14621d8..2d0c13bc423 100644
--- a/source/blender/blenlib/BLI_fnmatch.h
+++ b/source/blender/blenlib/BLI_fnmatch.h
@@ -16,7 +16,7 @@
* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
*
* NOTE: The canonical source of this file is maintained with the GNU C Library.
- * Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+ * Bugs can be reported to <bug-glibc@prep.ai.mit.edu>.
*/
#pragma once
diff --git a/source/blender/blenlib/BLI_math.h b/source/blender/blenlib/BLI_math.h
index 51833d081d0..f6075367ac5 100644
--- a/source/blender/blenlib/BLI_math.h
+++ b/source/blender/blenlib/BLI_math.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 0ec65999006..c862290b262 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_bits.h b/source/blender/blenlib/BLI_math_bits.h
index b007dd7cfed..e881f1a0e4e 100644
--- a/source/blender/blenlib/BLI_math_bits.h
+++ b/source/blender/blenlib/BLI_math_bits.h
@@ -12,8 +12,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 9e613270538..26d2f1fcb29 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h
index d5e4eedb1a6..2aff629def8 100644
--- a/source/blender/blenlib/BLI_math_color_blend.h
+++ b/source/blender/blenlib/BLI_math_color_blend.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index c0a9ea91e75..d767c2924d1 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
@@ -826,6 +825,11 @@ MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[
float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]);
+/********************************** Geodesics *********************************/
+
+float geodesic_distance_propagate_across_triangle(
+ const float v0[3], const float v1[3], const float v2[3], const float dist1, const float dist2);
+
/**************************** Inline Definitions ******************************/
#if BLI_MATH_DO_INLINE
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h
index 506386f8d25..70f56d15164 100644
--- a/source/blender/blenlib/BLI_math_inline.h
+++ b/source/blender/blenlib/BLI_math_inline.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index d971f48c4cf..eac7f25f11a 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -17,7 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index 15d4dc21f8d..fe995b2e46e 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
@@ -178,7 +177,7 @@ typedef enum eEulerRotationOrders {
EULER_ORDER_YZX,
EULER_ORDER_ZXY,
EULER_ORDER_ZYX,
- /* there are 6 more entries with dulpicate entries included */
+ /* There are 6 more entries with duplicate entries included. */
} eEulerRotationOrders;
void eulO_to_quat(float quat[4], const float eul[3], const short order);
diff --git a/source/blender/blenlib/BLI_math_solvers.h b/source/blender/blenlib/BLI_math_solvers.h
index 9b2d1eedec7..13481e27e2a 100644
--- a/source/blender/blenlib/BLI_math_solvers.h
+++ b/source/blender/blenlib/BLI_math_solvers.h
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2015 by Blender Foundation
* All rights reserved.
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_statistics.h b/source/blender/blenlib/BLI_math_statistics.h
index ad6cb1a3c1e..6e818f5c8df 100644
--- a/source/blender/blenlib/BLI_math_statistics.h
+++ b/source/blender/blenlib/BLI_math_statistics.h
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2015 by Blender Foundation
* All rights reserved.
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 16585e34419..bb1e1a1c38d 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
#pragma once
diff --git a/source/blender/blenlib/BLI_mesh_intersect.hh b/source/blender/blenlib/BLI_mesh_intersect.hh
index ddda3edf2ff..a7996939bb1 100644
--- a/source/blender/blenlib/BLI_mesh_intersect.hh
+++ b/source/blender/blenlib/BLI_mesh_intersect.hh
@@ -95,7 +95,7 @@ struct Plane {
/* Test equality on the exact fields. */
bool operator==(const Plane &other) const;
- /* Hash onthe exact fields. */
+ /* Hash on the exact fields. */
uint64_t hash() const;
void make_canonical();
@@ -144,7 +144,7 @@ struct Face : NonCopyable {
/* Test equality of verts, in same positions. */
bool operator==(const Face &other) const;
- /* Test equaliy faces allowing cyclic shifts. */
+ /* Test equality faces allowing cyclic shifts. */
bool cyclic_equal(const Face &other) const;
FacePos next_pos(FacePos p) const
diff --git a/source/blender/blenlib/BLI_mmap.h b/source/blender/blenlib/BLI_mmap.h
new file mode 100644
index 00000000000..4920152c9d1
--- /dev/null
+++ b/source/blender/blenlib/BLI_mmap.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ */
+
+#include "BLI_compiler_attrs.h"
+#include "BLI_utildefines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Memory-mapped file IO that implements all the OS-specific details and error handling. */
+
+struct BLI_mmap_file;
+
+typedef struct BLI_mmap_file BLI_mmap_file;
+
+/* Prepares an opened file for memory-mapped IO.
+ * May return NULL if the operation fails.
+ * Note that this seeks to the end of the file to determine its length. */
+BLI_mmap_file *BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+
+/* Reads length bytes from file at the given offset into dest.
+ * Returns whether the operation was successful (may fail when reading beyond the file
+ * end or when IO errors occur). */
+bool BLI_mmap_read(BLI_mmap_file *file, void *dest, size_t offset, size_t length)
+ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+
+void *BLI_mmap_get_pointer(BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT;
+
+void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenlib/BLI_sys_types.h b/source/blender/blenlib/BLI_sys_types.h
index ff1f6af9573..2740e3740f2 100644
--- a/source/blender/blenlib/BLI_sys_types.h
+++ b/source/blender/blenlib/BLI_sys_types.h
@@ -40,7 +40,7 @@ extern "C" {
#if defined(__linux__) || defined(__GNU__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
defined(__FreeBSD_kernel__) || defined(__HAIKU__)
-/* Linux-i386, Linux-Alpha, Linux-ppc */
+/* Linux-i386, Linux-Alpha, Linux-PPC */
# include <stdint.h>
/* XXX */
diff --git a/source/blender/blenlib/BLI_system.h b/source/blender/blenlib/BLI_system.h
index 8dd0706e1e2..0d5b2e6e2df 100644
--- a/source/blender/blenlib/BLI_system.h
+++ b/source/blender/blenlib/BLI_system.h
@@ -49,7 +49,7 @@ void BLI_hostname_get(char *buffer, size_t bufsize);
size_t BLI_system_memory_max_in_megabytes(void);
int BLI_system_memory_max_in_megabytes_int(void);
-/* getpid */
+/* For `getpid`. */
#ifdef WIN32
# define BLI_SYSTEM_PID_H <process.h>
diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh
index 0da03d84793..8e963c958b2 100644
--- a/source/blender/blenlib/BLI_task.hh
+++ b/source/blender/blenlib/BLI_task.hh
@@ -22,15 +22,15 @@
#ifdef WITH_TBB
/* Quiet top level deprecation message, unrelated to API usage here. */
-# define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
-
# if defined(WIN32) && !defined(NOMINMAX)
/* TBB includes Windows.h which will define min/max macros causing issues
* when we try to use std::min and std::max later on. */
# define NOMINMAX
# define TBB_MIN_MAX_CLEANUP
# endif
-# include <tbb/tbb.h>
+# include <tbb/blocked_range.h>
+# include <tbb/parallel_for.h>
+# include <tbb/parallel_for_each.h>
# ifdef WIN32
/* We cannot keep this defined, since other parts of the code deal with this on their own, leading
* to multiple define warnings unless we un-define this, however we can only undefine this if we
diff --git a/source/blender/blenlib/BLI_voronoi_2d.h b/source/blender/blenlib/BLI_voronoi_2d.h
index 92c7d367b48..0e27229352f 100644
--- a/source/blender/blenlib/BLI_voronoi_2d.h
+++ b/source/blender/blenlib/BLI_voronoi_2d.h
@@ -50,7 +50,7 @@ typedef struct VoronoiEdge {
/* point on Voronoi place on the right side of edge */
float right[2];
- /* directional coeffitients satisfying equation y = f * x + g (edge lies on this line) */
+ /* Directional coefficients satisfying equation `y = f * x + g` (edge lies on this line). */
float f, g;
/* some edges consist of two parts,
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index dc4d6d8fce4..f771d26baab 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -64,7 +64,7 @@ extern "C" {
# define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
#endif
-/* defines for using ISO C++ conformant names */
+/* Defines for using ISO C++ conferment names. */
#if !defined(_MSC_VER) || _MSC_VER < 1900
# define snprintf _snprintf
#endif
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 45a1054fb53..363d3003b3c 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -54,6 +54,7 @@ set(SRC
intern/BLI_memblock.c
intern/BLI_memiter.c
intern/BLI_mempool.c
+ intern/BLI_mmap.c
intern/BLI_timer.c
intern/DLRB_tree.c
intern/array_store.c
@@ -243,6 +244,7 @@ set(SRC
BLI_mempool.h
BLI_mesh_boolean.hh
BLI_mesh_intersect.hh
+ BLI_mmap.h
BLI_mpq2.hh
BLI_mpq3.hh
BLI_multi_value_map.hh
diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c
index fe3ec368379..cc01693422c 100644
--- a/source/blender/blenlib/intern/BLI_filelist.c
+++ b/source/blender/blenlib/intern/BLI_filelist.c
@@ -369,7 +369,7 @@ void BLI_filelist_entry_datetime_to_string(const struct stat *st,
int yesterday_yday = 0;
if (r_is_today || r_is_yesterday) {
- /* Localtime() has only one buffer so need to get data out before called again. */
+ /* `localtime()` has only one buffer so need to get data out before called again. */
const time_t ts_now = time(NULL);
struct tm *today = localtime(&ts_now);
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 0f90ad3a490..a0e94e00634 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -94,7 +94,7 @@ struct BVHTree {
BVHNode *nodearray; /* pre-alloc branch nodes */
BVHNode **nodechild; /* pre-alloc children for nodes */
float *nodebv; /* pre-alloc bounding-volumes for nodes */
- float epsilon; /* epslion is used for inflation of the k-dop */
+ float epsilon; /* Epsilon is used for inflation of the K-DOP. */
int totleaf; /* leafs */
int totbranch;
axis_t start_axis, stop_axis; /* bvhtree_kdop_axes array indices according to axis */
@@ -365,7 +365,7 @@ static void create_kdop_hull(
int k;
axis_t axis_iter;
- /* don't init boudings for the moving case */
+ /* Don't initialize bounds for the moving case */
if (!moving) {
node_minmax_init(tree, node);
}
@@ -573,9 +573,9 @@ typedef struct BVHBuildHelper {
int tree_type;
int totleafs;
- /** Min number of leafs that are archievable from a node at depth N */
+ /** Min number of leafs that are achievable from a node at depth `N`. */
int leafs_per_child[32];
- /** Number of nodes at depth N (tree_type^N) */
+ /** Number of nodes at depth `N (tree_type^N)`. */
int branches_on_level[32];
/** Number of leafs that are placed on the level that is not 100% filled */
@@ -1312,7 +1312,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap_ex(
bool use_threading = (flag & BVH_OVERLAP_USE_THREADING) != 0 &&
(tree1->totleaf > KDOPBVH_THREAD_LEAF_THRESHOLD);
- /* `RETURN_PAIRS` was not implemented without `max_interations`. */
+ /* 'RETURN_PAIRS' was not implemented without 'max_interactions'. */
BLI_assert(overlap_pairs || max_interactions);
const int root_node_len = BLI_bvhtree_overlap_thread_num(tree1);
diff --git a/source/blender/blenlib/intern/BLI_mmap.c b/source/blender/blenlib/intern/BLI_mmap.c
new file mode 100644
index 00000000000..2fd162de22c
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_mmap.c
@@ -0,0 +1,237 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#include "BLI_mmap.h"
+#include "BLI_fileops.h"
+#include "BLI_listbase.h"
+#include "MEM_guardedalloc.h"
+
+#include <string.h>
+
+#ifndef WIN32
+# include <signal.h>
+# include <stdlib.h>
+# include <sys/mman.h> // for mmap
+# include <unistd.h> // for read close
+#else
+# include "BLI_winstuff.h"
+# include <io.h> // for open close read
+#endif
+
+struct BLI_mmap_file {
+ /* The address to which the file was mapped. */
+ char *memory;
+
+ /* The length of the file (and therefore the mapped region). */
+ size_t length;
+
+ /* Platform-specific handle for the mapping. */
+ void *handle;
+
+ /* Flag to indicate IO errors. Needs to be volatile since it's being set from
+ * within the signal handler, which is not part of the normal execution flow. */
+ volatile bool io_error;
+};
+
+#ifndef WIN32
+/* When using memory-mapped files, any IO errors will result in a SIGBUS signal.
+ * Therefore, we need to catch that signal and stop reading the file in question.
+ * To do so, we keep a list of all current FileDatas that use memory-mapped files,
+ * and if a SIGBUS is caught, we check if the failed address is inside one of the
+ * mapped regions.
+ * If it is, we set a flag to indicate a failed read and remap the memory in
+ * question to a zero-backed region in order to avoid additional signals.
+ * The code that actually reads the memory area has to check whether the flag was
+ * set after it's done reading.
+ * If the error occurred outside of a memory-mapped region, we call the previous
+ * handler if one was configured and abort the process otherwise.
+ */
+
+struct error_handler_data {
+ ListBase open_mmaps;
+ char configured;
+ void (*next_handler)(int, siginfo_t *, void *);
+} error_handler = {0};
+
+static void sigbus_handler(int sig, siginfo_t *siginfo, void *ptr)
+{
+ /* We only handle SIGBUS here for now. */
+ BLI_assert(sig == SIGBUS);
+
+ char *error_addr = (char *)siginfo->si_addr;
+ /* Find the file that this error belongs to. */
+ LISTBASE_FOREACH (LinkData *, link, &error_handler.open_mmaps) {
+ BLI_mmap_file *file = link->data;
+
+ /* Is the address where the error occurred in this file's mapped range? */
+ if (error_addr >= file->memory && error_addr < file->memory + file->length) {
+ file->io_error = true;
+
+ /* Replace the mapped memory with zeroes. */
+ const void *mapped_memory = mmap(
+ file->memory, file->length, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ if (mapped_memory == MAP_FAILED) {
+ fprintf(stderr, "SIGBUS handler: Error replacing mapped file with zeros\n");
+ }
+
+ return;
+ }
+ }
+
+ /* Fall back to other handler if there was one. */
+ if (error_handler.next_handler) {
+ error_handler.next_handler(sig, siginfo, ptr);
+ }
+ else {
+ fprintf(stderr, "Unhandled SIGBUS caught\n");
+ abort();
+ }
+}
+
+/* Ensures that the error handler is set up and ready. */
+static bool sigbus_handler_setup(void)
+{
+ if (!error_handler.configured) {
+ struct sigaction newact = {0}, oldact = {0};
+
+ newact.sa_sigaction = sigbus_handler;
+ newact.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGBUS, &newact, &oldact)) {
+ return false;
+ }
+
+ /* Remember the previously configured handler to fall back to it if the error
+ * does not belong to any of the mapped files. */
+ error_handler.next_handler = oldact.sa_sigaction;
+ error_handler.configured = 1;
+ }
+
+ return true;
+}
+
+/* Adds a file to the list that the error handler checks. */
+static void sigbus_handler_add(BLI_mmap_file *file)
+{
+ BLI_addtail(&error_handler.open_mmaps, BLI_genericNodeN(file));
+}
+
+/* Removes a file from the list that the error handler checks. */
+static void sigbus_handler_remove(BLI_mmap_file *file)
+{
+ LinkData *link = BLI_findptr(&error_handler.open_mmaps, file, offsetof(LinkData, data));
+ BLI_freelinkN(&error_handler.open_mmaps, link);
+}
+#endif
+
+BLI_mmap_file *BLI_mmap_open(int fd)
+{
+ void *memory, *handle = NULL;
+ size_t length = BLI_lseek(fd, 0, SEEK_END);
+
+#ifndef WIN32
+ /* Ensure that the SIGBUS handler is configured. */
+ if (!sigbus_handler_setup()) {
+ return NULL;
+ }
+
+ /* Map the given file to memory. */
+ memory = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (memory == MAP_FAILED) {
+ return NULL;
+ }
+#else
+ /* Convert the POSIX-style file descriptor to a Windows handle. */
+ void *file_handle = (void *)_get_osfhandle(fd);
+ /* Memory mapping on Windows is a two-step process - first we create a mapping,
+ * then we create a view into that mapping.
+ * In our case, one view that spans the entire file is enough. */
+ handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (handle == NULL) {
+ return NULL;
+ }
+ memory = MapViewOfFile(handle, FILE_MAP_READ, 0, 0, 0);
+ if (memory == NULL) {
+ CloseHandle(handle);
+ return NULL;
+ }
+#endif
+
+ /* Now that the mapping was successful, allocate memory and set up the BLI_mmap_file. */
+ BLI_mmap_file *file = MEM_callocN(sizeof(BLI_mmap_file), __func__);
+ file->memory = memory;
+ file->handle = handle;
+ file->length = length;
+
+#ifndef WIN32
+ /* Register the file with the error handler. */
+ sigbus_handler_add(file);
+#endif
+
+ return file;
+}
+
+bool BLI_mmap_read(BLI_mmap_file *file, void *dest, size_t offset, size_t length)
+{
+ /* If a previous read has already failed or we try to read past the end,
+ * don't even attempt to read any further. */
+ if (file->io_error || (offset + length > file->length)) {
+ return false;
+ }
+
+#ifndef WIN32
+ /* If an error occurs in this call, sigbus_handler will be called and will set
+ * file->io_error to true. */
+ memcpy(dest, file->memory + offset, length);
+#else
+ /* On Windows, we use exception handling to be notified of errors. */
+ __try {
+ memcpy(dest, file->memory + offset, length);
+ }
+ __except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR ? EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH) {
+ file->io_error = true;
+ return false;
+ }
+#endif
+
+ return !file->io_error;
+}
+
+void *BLI_mmap_get_pointer(BLI_mmap_file *file)
+{
+ return file->memory;
+}
+
+void BLI_mmap_free(BLI_mmap_file *file)
+{
+#ifndef WIN32
+ munmap((void *)file->memory, file->length);
+ sigbus_handler_remove(file);
+#else
+ UnmapViewOfFile(file->memory);
+ CloseHandle(file->handle);
+#endif
+
+ MEM_freeN(file);
+}
diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c
index 847cb42186a..08164e75009 100644
--- a/source/blender/blenlib/intern/array_store.c
+++ b/source/blender/blenlib/intern/array_store.c
@@ -533,7 +533,7 @@ static void bchunk_list_calc_trim_len(const BArrayInfo *info,
data_trim_len = data_trim_len - data_last_chunk_len;
if (data_last_chunk_len) {
if (data_last_chunk_len < info->chunk_byte_size_min) {
- /* may be zero and thats OK */
+ /* May be zero and that's OK. */
data_trim_len -= info->chunk_byte_size;
data_last_chunk_len += info->chunk_byte_size;
}
diff --git a/source/blender/blenlib/intern/bitmap_draw_2d.c b/source/blender/blenlib/intern/bitmap_draw_2d.c
index 33250105c79..9d3b66d72d7 100644
--- a/source/blender/blenlib/intern/bitmap_draw_2d.c
+++ b/source/blender/blenlib/intern/bitmap_draw_2d.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index 9840dc77148..84b3f728884 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -385,7 +385,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
box++; /* next box, needed for the loop below */
/* ...done packing the first box */
- /* Main boxpacking loop */
+ /* Main box-packing loop */
for (box_index = 1; box_index < len; box_index++, box++) {
/* These floats are used for sorting re-sorting */
@@ -414,8 +414,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
/* This vert has a free quadrant
* Test if we can place the box here
- * vert->free & quad_flags[j] - Checks
- * */
+ * `vert->free & quad_flags[j]` - Checks. */
for (j = 0; (j < 4) && isect; j++) {
if (vert->free & quad_flag(j)) {
diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c
index a3d24787d27..cb4ef54bfb7 100644
--- a/source/blender/blenlib/intern/convexhull_2d.c
+++ b/source/blender/blenlib/intern/convexhull_2d.c
@@ -28,7 +28,7 @@
#include "BLI_strict_flags.h"
#include "BLI_utildefines.h"
-/* Copyright 2001, softSurfer (www.softsurfer.com)
+/* Copyright 2001, softSurfer (http://www.softsurfer.com)
* This code may be freely used and modified for any purpose
* providing that this copyright notice is included with it.
* SoftSurfer makes no warranty for this code, and cannot be held
diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc
index f0b65a55816..06a749ab921 100644
--- a/source/blender/blenlib/intern/delaunay_2d.cc
+++ b/source/blender/blenlib/intern/delaunay_2d.cc
@@ -561,14 +561,14 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
const vec2<double> &uco = u->co.approx;
const vec2<double> &vco = v->co.approx;
int strokew = e->input_ids == nullptr ? thin_line : thick_line;
- f << "<line fill=\"none\" stroke=\"black\" stroke-width=\"" << strokew << "\" x1=\""
+ f << R"(<line fill="none" stroke="black" stroke-width=")" << strokew << "\" x1=\""
<< SX(uco[0]) << "\" y1=\"" << SY(uco[1]) << "\" x2=\"" << SX(vco[0]) << "\" y2=\""
<< SY(vco[1]) << "\">\n";
f << " <title>" << vertname(u) << vertname(v) << "</title>\n";
f << "</line>\n";
if (draw_edge_labels) {
f << "<text x=\"" << SX((uco[0] + vco[0]) / 2) << "\" y=\"" << SY((uco[1] + vco[1]) / 2)
- << "\" font-size=\"small\">";
+ << R"(" font-size="small">)";
f << vertname(u) << vertname(v) << sename(&e->symedges[0]) << sename(&e->symedges[1])
<< "</text>\n";
}
@@ -576,13 +576,13 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
int i = 0;
for (const CDTVert<T> *v : cdt.verts) {
- f << "<circle fill=\"black\" cx=\"" << SX(v->co.approx[0]) << "\" cy=\"" << SY(v->co.approx[1])
+ f << R"(<circle fill="black" cx=")" << SX(v->co.approx[0]) << "\" cy=\"" << SY(v->co.approx[1])
<< "\" r=\"" << vert_radius << "\">\n";
f << " <title>[" << i << "]" << v->co.approx << "</title>\n";
f << "</circle>\n";
if (draw_vert_labels) {
f << "<text x=\"" << SX(v->co.approx[0]) + vert_radius << "\" y=\""
- << SY(v->co.approx[1]) - vert_radius << "\" font-size=\"small\">[" << i << "]</text>\n";
+ << SY(v->co.approx[1]) - vert_radius << R"(" font-size="small">[)" << i << "]</text>\n";
}
++i;
}
@@ -754,7 +754,7 @@ template<> CDTVert<double>::CDTVert(const vec2<double> &pt)
{
this->co.exact = pt;
this->co.approx = pt;
- this->co.abs_approx = pt; /* Not used, so does't matter. */
+ this->co.abs_approx = pt; /* Not used, so doesn't matter. */
this->input_ids = nullptr;
this->symedge = nullptr;
this->index = -1;
@@ -1411,12 +1411,12 @@ void dc_tri(CDTArrangement<T> *cdt,
/* Guibas-Stolfi Divide-and_Conquer algorithm. */
template<typename T> void dc_triangulate(CDTArrangement<T> *cdt, Array<SiteInfo<T>> &sites)
{
- /* Compress sites in place to eliminted verts that merge to others. */
+ /* Compress sites in place to eliminated verts that merge to others. */
int i = 0;
int j = 0;
int nsites = sites.size();
while (j < nsites) {
- /* Invariante: sites[0..i-1] have non-merged verts from 0..(j-1) in them. */
+ /* Invariant: `sites[0..i-1]` have non-merged verts from `0..(j-1)` in them. */
sites[i] = sites[j++];
if (sites[i].v->merge_to_index < 0) {
i++;
@@ -1500,7 +1500,7 @@ template<typename T> static void re_delaunay_triangulate(CDTArrangement<T> *cdt,
cse = ss;
}
}
- /* Add diagonals necessary to make abc a triangle. */
+ /* Add diagonals necessary to make `abc` a triangle. */
CDTEdge<T> *ebc = nullptr;
CDTEdge<T> *eca = nullptr;
if (!exists_edge(b, c)) {
diff --git a/source/blender/blenlib/intern/dot_export.cc b/source/blender/blenlib/intern/dot_export.cc
index eb15a51366e..13a2341a9d5 100644
--- a/source/blender/blenlib/intern/dot_export.cc
+++ b/source/blender/blenlib/intern/dot_export.cc
@@ -275,10 +275,10 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node,
{
std::stringstream ss;
- ss << "<<table border=\"0\" cellspacing=\"3\">";
+ ss << R"(<<table border="0" cellspacing="3">)";
/* Header */
- ss << "<tr><td colspan=\"3\" align=\"center\"><b>";
+ ss << R"(<tr><td colspan="3" align="center"><b>)";
ss << ((name.size() == 0) ? "No Name" : name);
ss << "</b></td></tr>";
@@ -291,7 +291,7 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node,
if (name.size() == 0) {
name = "No Name";
}
- ss << "<td align=\"left\" port=\"in" << i << "\">";
+ ss << R"(<td align="left" port="in)" << i << "\">";
ss << name;
ss << "</td>";
}
@@ -304,7 +304,7 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node,
if (name.size() == 0) {
name = "No Name";
}
- ss << "<td align=\"right\" port=\"out" << i << "\">";
+ ss << R"(<td align="right" port="out)" << i << "\">";
ss << name;
ss << "</td>";
}
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 301d9dc2296..e755a8e75b5 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -307,7 +307,7 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
/* Extract the first 256 character from TTF */
lcode = charcode = FT_Get_First_Char(face, &glyph_index);
- /* No charmap found from the ttf so we need to figure it out */
+ /* No `charmap` found from the TTF so we need to figure it out. */
if (glyph_index == 0) {
FT_CharMap found = NULL;
FT_CharMap charmap;
diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c
index 118d19418d4..ae34074e804 100644
--- a/source/blender/blenlib/intern/gsqueue.c
+++ b/source/blender/blenlib/intern/gsqueue.c
@@ -41,7 +41,7 @@ struct QueueChunk {
struct _GSQueue {
struct QueueChunk *chunk_first; /* first active chunk to pop from */
- struct QueueChunk *chunk_last; /* flast active chunk to push onto */
+ struct QueueChunk *chunk_last; /* last active chunk to push onto */
struct QueueChunk *chunk_free; /* free chunks to reuse */
size_t chunk_first_index; /* index into 'chunk_first' */
size_t chunk_last_index; /* index into 'chunk_last' */
diff --git a/source/blender/blenlib/intern/jitter_2d.c b/source/blender/blenlib/intern/jitter_2d.c
index c92aeddb27d..068cb3d2f70 100644
--- a/source/blender/blenlib/intern/jitter_2d.c
+++ b/source/blender/blenlib/intern/jitter_2d.c
@@ -179,7 +179,7 @@ void BLI_jitter_init(float (*jitarr)[2], int num)
MEM_freeN(jit2);
- /* finally, move jittertab to be centered around (0, 0) */
+ /* Finally, move jitter to be centered around (0, 0). */
for (i = 0; i < num; i++) {
jitarr[i][0] -= 0.5f;
jitarr[i][1] -= 0.5f;
diff --git a/source/blender/blenlib/intern/kdtree_impl.h b/source/blender/blenlib/intern/kdtree_impl.h
index 26b2228cdbc..c92dc2e95a3 100644
--- a/source/blender/blenlib/intern/kdtree_impl.h
+++ b/source/blender/blenlib/intern/kdtree_impl.h
@@ -158,7 +158,7 @@ static uint kdtree_balance(KDTreeNode *nodes, uint nodes_len, uint axis, const u
return 0 + ofs;
}
- /* quicksort style sorting around median */
+ /* Quick-sort style sorting around median. */
left = 0;
right = nodes_len - 1;
median = nodes_len / 2;
diff --git a/source/blender/blenlib/intern/list_sort_impl.h b/source/blender/blenlib/intern/list_sort_impl.h
index 46738803ee8..8f979ba5b0b 100644
--- a/source/blender/blenlib/intern/list_sort_impl.h
+++ b/source/blender/blenlib/intern/list_sort_impl.h
@@ -205,7 +205,7 @@ BLI_INLINE list_node *sweep_up(struct SortInfo *si, list_node *list, unsigned in
* The 'ranks' array essentially captures the recursion stack of a mergesort.
* The merge tree is built in a bottom-up manner. The control loop for
* updating the 'ranks' array is analogous to incrementing a binary integer,
- * and the `O(n)` time for counting upto n translates to `O(n)` merges when
+ * and the `O(n)` time for counting `upto` n translates to `O(n)` merges when
* inserting `rank-0` lists.
* When we plug in the sizes of the lists involved in those merges,
* we get the `O(n log n)` time for the sort.
diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c
index 2bf06371740..1137c4114a5 100644
--- a/source/blender/blenlib/intern/math_base.c
+++ b/source/blender/blenlib/intern/math_base.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index 1dc7c21f1d4..28aa81e5858 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
@@ -380,7 +379,7 @@ MINLINE float fractf(float a)
return a - floorf(a);
}
-/* Adapted from godotengine math_funcs.h. */
+/* Adapted from godot-engine math_funcs.h. */
MINLINE float wrapf(float value, float max, float min)
{
float range = max - min;
@@ -717,7 +716,7 @@ MALWAYS_INLINE __m128 _bli_math_improve_5throot_solution(const __m128 old_result
__m128 approx2 = _mm_mul_ps(old_result, old_result);
__m128 approx4 = _mm_mul_ps(approx2, approx2);
__m128 t = _mm_div_ps(x, approx4);
- __m128 summ = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(4.0f), old_result), t); /* fma */
+ __m128 summ = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(4.0f), old_result), t); /* FMA. */
return _mm_mul_ps(summ, _mm_set1_ps(1.0f / 5.0f));
}
diff --git a/source/blender/blenlib/intern/math_bits_inline.c b/source/blender/blenlib/intern/math_bits_inline.c
index ba18bb73850..1b381dccbfd 100644
--- a/source/blender/blenlib/intern/math_bits_inline.c
+++ b/source/blender/blenlib/intern/math_bits_inline.c
@@ -12,8 +12,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_boolean.cc b/source/blender/blenlib/intern/math_boolean.cc
index a345bc1d0af..6d4806a3fbc 100644
--- a/source/blender/blenlib/intern/math_boolean.cc
+++ b/source/blender/blenlib/intern/math_boolean.cc
@@ -160,7 +160,7 @@ static RobustInitCaller init_caller;
* Carnegie Mellon University
* 5000 Forbes Avenue
* Pittsburgh, Pennsylvania 15213-3891
- * jrs@cs.cmu.edu
+ * <jrs@cs.cmu.edu>
*
* This file contains C implementation of algorithms for exact addition
* and multiplication of floating-point numbers, and predicates for
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 31ee81de40e..8fd2802a547 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c
index 7ad4f0d9585..53257cc9285 100644
--- a/source/blender/blenlib/intern/math_color_blend_inline.c
+++ b/source/blender/blenlib/intern/math_color_blend_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
index 1264620cf36..26828cb8717 100644
--- a/source/blender/blenlib/intern/math_color_inline.c
+++ b/source/blender/blenlib/intern/math_color_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
@@ -42,7 +41,7 @@ MALWAYS_INLINE __m128 srgb_to_linearrgb_v4_simd(const __m128 c)
__m128 cmp = _mm_cmplt_ps(c, _mm_set1_ps(0.04045f));
__m128 lt = _mm_max_ps(_mm_mul_ps(c, _mm_set1_ps(1.0f / 12.92f)), _mm_set1_ps(0.0f));
__m128 gtebase = _mm_mul_ps(_mm_add_ps(c, _mm_set1_ps(0.055f)),
- _mm_set1_ps(1.0f / 1.055f)); /* fma */
+ _mm_set1_ps(1.0f / 1.055f)); /* FMA. */
__m128 gte = _bli_math_fastpow24(gtebase);
return _bli_math_blend_sse(cmp, lt, gte);
}
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 3cc4d03d547..5d78bb0b901 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
@@ -1439,12 +1438,12 @@ int isect_line_sphere_v3(const float l1[3],
/* adapted for use in blender by Campbell Barton - 2011
*
* atelier iebele abel - 2001
- * atelier@iebele.nl
+ * <atelier@iebele.nl>
* http://www.iebele.nl
*
* sphere_line_intersection function adapted from:
* http://astronomy.swin.edu.au/pbourke/geometry/sphereline
- * Paul Bourke pbourke@swin.edu.au
+ * Paul Bourke <pbourke@swin.edu.au>
*/
const float ldir[3] = {
@@ -3887,7 +3886,7 @@ void interp_weights_quad_v3(float w[4],
* - 0 if the point is outside of triangle.
* - 1 if the point is inside triangle.
* - 2 if it's on the edge.
- * */
+ */
int barycentric_inside_triangle_v2(const float w[3])
{
if (IN_RANGE(w[0], 0.0f, 1.0f) && IN_RANGE(w[1], 0.0f, 1.0f) && IN_RANGE(w[2], 0.0f, 1.0f)) {
@@ -5234,7 +5233,7 @@ void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f
len = sqrtf(x * x + y * y + z * z);
if (len > 0.0f) {
if (UNLIKELY(x == 0.0f && y == 0.0f)) {
- *r_u = 0.0f; /* othwise domain error */
+ *r_u = 0.0f; /* Otherwise domain error. */
}
else {
*r_u = (1.0f - atan2f(x, y) / (float)M_PI) / 2.0f;
@@ -5837,7 +5836,7 @@ bool form_factor_visible_quad(const float p[3],
return true;
}
-/* altivec optimization, this works, but is unused */
+/* `AltiVec` optimization, this works, but is unused. */
#if 0
# include <Accelerate/Accelerate.h>
@@ -6126,7 +6125,7 @@ bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3],
bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
- /* linetests, the 2 diagonals have to instersect to be convex */
+ /* Line-tests, the 2 diagonals have to intersect to be convex. */
return (isect_seg_seg_v2(v1, v3, v2, v4) > 0);
}
@@ -6234,7 +6233,7 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
return (1.0f / 3.0f) * 0.75f;
}
if (tan_dot < -1.0f + eps) {
- /* parallele tangents (half-circle) */
+ /* Parallel tangents (half-circle). */
return (1.0f / 2.0f);
}
@@ -6246,3 +6245,56 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
const float angle_cos = cosf(angle);
return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
}
+
+/**
+ * Utility for computing approximate geodesic distances on triangle meshes.
+ *
+ * Given triangle with vertex coordinates v0, v1, v2, and known geodesic distances
+ * dist1 and dist2 at v1 and v2, estimate a geodesic distance at vertex v0.
+ *
+ * From "Dart Throwing on Surfaces", EGSR 2009. Section 7, Geodesic Dart Throwing.
+ */
+float geodesic_distance_propagate_across_triangle(
+ const float v0[3], const float v1[3], const float v2[3], const float dist1, const float dist2)
+{
+ /* Vectors along triangle edges. */
+ float v10[3], v12[3];
+ sub_v3_v3v3(v10, v0, v1);
+ sub_v3_v3v3(v12, v2, v1);
+
+ if (dist1 != 0.0f && dist2 != 0.0f) {
+ /* Local coordinate system in the triangle plane. */
+ float u[3], v[3], n[3];
+ const float d12 = normalize_v3_v3(u, v12);
+
+ if (d12 * d12 > 0.0f) {
+ cross_v3_v3v3(n, v12, v10);
+ normalize_v3(n);
+ cross_v3_v3v3(v, n, u);
+
+ /* v0 in local coordinates */
+ const float v0_[2] = {dot_v3v3(v10, u), fabsf(dot_v3v3(v10, v))};
+
+ /* Compute virtual source point in local coordinates, that we estimate the geodesic
+ * distance is being computed from. See figure 9 in the paper for the derivation. */
+ const float a = 0.5f * (1.0f + (dist1 * dist1 - dist2 * dist2) / (d12 * d12));
+ const float hh = dist1 * dist1 - a * a * d12 * d12;
+
+ if (hh > 0.0f) {
+ const float h = sqrtf(hh);
+ const float S_[2] = {a * d12, -h};
+
+ /* Only valid if the line between the source point and v0 crosses
+ * the edge between v1 and v2. */
+ const float x_intercept = S_[0] + h * (v0_[0] - S_[0]) / (v0_[1] + h);
+ if (x_intercept >= 0.0f && x_intercept <= d12) {
+ return len_v2v2(S_, v0_);
+ }
+ }
+ }
+ }
+
+ /* Fall back to Dijsktra approximation in trivial case, or if no valid source
+ * point found that connects to v0 across the triangle. */
+ return min_ff(dist1 + len_v3(v10), dist2 + len_v3v3(v0, v2));
+}
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
index db317f5e81d..23c351026f2 100644
--- a/source/blender/blenlib/intern/math_geom_inline.c
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c
index 3cec3db9806..163a3ab5fe3 100644
--- a/source/blender/blenlib/intern/math_interp.c
+++ b/source/blender/blenlib/intern/math_interp.c
@@ -139,10 +139,10 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
y1 = j + m;
CLAMP(y1, 0, height - 1);
- /* normally we could do this */
- /* w = P(n-a) * P(b-m); */
- /* except that would call P() 16 times per pixel therefor pow() 64 times,
- * better precalc these */
+ /* Normally we could do this:
+ * `w = P(n-a) * P(b-m);`
+ * except that would call `P()` 16 times per pixel therefor `pow()` 64 times,
+ * better pre-calculate these. */
w = wx * wy[m + 1];
if (float_output) {
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 19828e69638..57fe99ce019 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -594,7 +594,7 @@ float quat_split_swing_and_twist(const float q_in[4], int axis, float r_swing[4]
BLI_assert(fabsf(r_swing[axis + 1]) < BLI_ASSERT_UNIT_EPSILON);
}
- /* Output twist last just in case q ovelaps r_twist. */
+ /* Output twist last just in case q overlaps r_twist. */
if (r_twist) {
r_twist[0] = cos_t;
zero_v3(r_twist + 1);
@@ -1581,7 +1581,7 @@ void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float qua
* was adapted from
* ANSI C code from the article
* "Euler Angle Conversion"
- * by Ken Shoemake, shoemake@graphics.cis.upenn.edu
+ * by Ken Shoemake <shoemake@graphics.cis.upenn.edu>
* in "Graphics Gems IV", Academic Press, 1994
* for use in Blender
*/
diff --git a/source/blender/blenlib/intern/math_solvers.c b/source/blender/blenlib/intern/math_solvers.c
index e366d834fc4..85900dc32a6 100644
--- a/source/blender/blenlib/intern/math_solvers.c
+++ b/source/blender/blenlib/intern/math_solvers.c
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2015 by Blender Foundation.
* All rights reserved.
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_statistics.c b/source/blender/blenlib/intern/math_statistics.c
index 18affbed708..b90ac99dbfe 100644
--- a/source/blender/blenlib/intern/math_statistics.c
+++ b/source/blender/blenlib/intern/math_statistics.c
@@ -15,7 +15,7 @@
*
* The Original Code is Copyright (C) 2015 by Blender Foundation.
* All rights reserved.
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_vec.cc b/source/blender/blenlib/intern/math_vec.cc
index 84fa6c69d17..1d138d0b0f4 100644
--- a/source/blender/blenlib/intern/math_vec.cc
+++ b/source/blender/blenlib/intern/math_vec.cc
@@ -104,7 +104,7 @@ mpq2::isect_result mpq2::isect_seg_seg(const mpq2 &v1,
}
else {
ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
- /* Avoid dividing mu by div: it is expensive in multiprecision. */
+ /* Avoid dividing mu by div: it is expensive in multi-precision. */
mpq_class mudiv = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1]));
if (ans.lambda >= 0 && ans.lambda <= 1 &&
((div > 0 && mudiv >= 0 && mudiv <= div) || (div < 0 && mudiv <= 0 && mudiv >= div))) {
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index da16fb4a9fb..a21e0c8f092 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index f17b7535258..ead354c2d87 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -17,8 +17,7 @@
* All rights reserved.
*
* The Original Code is: some of this file.
- *
- * */
+ */
/** \file
* \ingroup bli
diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc
index 88d90a7816f..6ca5be743f0 100644
--- a/source/blender/blenlib/intern/mesh_boolean.cc
+++ b/source/blender/blenlib/intern/mesh_boolean.cc
@@ -27,10 +27,14 @@
# include "BLI_array.hh"
# include "BLI_assert.h"
# include "BLI_delaunay_2d.h"
+# include "BLI_double3.hh"
+# include "BLI_float3.hh"
# include "BLI_hash.hh"
+# include "BLI_kdopbvh.h"
# include "BLI_map.hh"
# include "BLI_math.h"
# include "BLI_math_boolean.hh"
+# include "BLI_math_geom.h"
# include "BLI_math_mpq.hh"
# include "BLI_mesh_intersect.hh"
# include "BLI_mpq3.hh"
@@ -45,6 +49,7 @@
# include "BLI_mesh_boolean.hh"
// # define PERFDEBUG
+
namespace blender::meshintersect {
/**
@@ -2328,159 +2333,216 @@ static const char *bool_optype_name(BoolOpType op)
}
}
-static mpq3 calc_point_inside_tri(const Face &tri)
+static double3 calc_point_inside_tri_db(const Face &tri)
{
const Vert *v0 = tri.vert[0];
const Vert *v1 = tri.vert[1];
const Vert *v2 = tri.vert[2];
- mpq3 ans = v0->co_exact / 3 + v1->co_exact / 3 + v2->co_exact / 3;
+ double3 ans = v0->co / 3 + v1->co / 3 + v2->co / 3;
return ans;
}
+class InsideShapeTestData {
+ public:
+ const IMesh &tm;
+ std::function<int(int)> shape_fn;
+ int nshapes;
+ /* A per-shape vector of parity of hits of that shape. */
+ Array<int> hit_parity;
+
+ InsideShapeTestData(const IMesh &tm, std::function<int(int)> shape_fn, int nshapes)
+ : tm(tm), shape_fn(shape_fn), nshapes(nshapes)
+ {
+ }
+};
-/**
- * Return the Generalized Winding Number of point \a testp with respect to the
- * volume implied by the faces for which shape_fn returns the value shape.
- * See "Robust Inside-Outside Segmentation using Generalized Winding Numbers"
- * by Jacobson, Kavan, and Sorkine-Hornung.
- * This is like a winding number in that if it is positive, the point
- * is inside the volume. But it is tolerant of not-completely-watertight
- * volumes, still doing a passable job of classifying inside/outside
- * as we intuitively understand that to mean.
- *
- * TOOD: speed up this calculation using the hierarchical algorithm in that paper.
- */
-static double generalized_winding_number(const IMesh &tm,
- std::function<int(int)> shape_fn,
- const double3 &testp,
- int shape)
+static void inside_shape_callback(void *userdata,
+ int index,
+ const BVHTreeRay *ray,
+ BVHTreeRayHit *UNUSED(hit))
{
- constexpr int dbg_level = 0;
+ const int dbg_level = 0;
if (dbg_level > 0) {
- std::cout << "GENERALIZED_WINDING_NUMBER testp = " << testp << ", shape = " << shape << "\n";
+ std::cout << "inside_shape_callback, index = " << index << "\n";
}
- double gwn = 0;
- for (int t : tm.face_index_range()) {
- const Face *f = tm.face(t);
- const Face &tri = *f;
- if (shape_fn(tri.orig) == shape) {
- if (dbg_level > 0) {
- std::cout << "accumulate for tri t = " << t << " = " << f << "\n";
- }
- const Vert *v0 = tri.vert[0];
- const Vert *v1 = tri.vert[1];
- const Vert *v2 = tri.vert[2];
- double3 a = v0->co - testp;
- double3 b = v1->co - testp;
- double3 c = v2->co - testp;
- /* Calculate the solid angle of abc relative to origin.
- * See "The Solid Angle of a Plane Triangle" by Oosterom and Strackee
- * for the derivation of the formula. */
- double alen = a.length();
- double blen = b.length();
- double clen = c.length();
- double3 bxc = double3::cross_high_precision(b, c);
- double num = double3::dot(a, bxc);
- double denom = alen * blen * clen + double3::dot(a, b) * clen + double3::dot(a, c) * blen +
- double3::dot(b, c) * alen;
- if (denom == 0.0) {
- if (dbg_level > 0) {
- std::cout << "denom == 0, skipping this tri\n";
- }
- continue;
- }
- double x = atan2(num, denom);
- double fgwn = 2.0 * x;
- if (dbg_level > 0) {
- std::cout << "tri contributes " << fgwn << "\n";
- }
- gwn += fgwn;
- }
+ InsideShapeTestData *data = static_cast<InsideShapeTestData *>(userdata);
+ const Face &tri = *data->tm.face(index);
+ int shape = data->shape_fn(tri.orig);
+ if (shape == -1) {
+ return;
+ }
+ float dist;
+ float fv0[3];
+ float fv1[3];
+ float fv2[3];
+ for (int i = 0; i < 3; ++i) {
+ fv0[i] = float(tri.vert[0]->co[i]);
+ fv1[i] = float(tri.vert[1]->co[i]);
+ fv2[i] = float(tri.vert[2]->co[i]);
}
- gwn = gwn / (M_PI * 4.0);
if (dbg_level > 0) {
- std::cout << "final gwn = " << gwn << "\n";
+ std::cout << " fv0=(" << fv0[0] << "," << fv0[1] << "," << fv0[2] << ")\n";
+ std::cout << " fv1=(" << fv1[0] << "," << fv1[1] << "," << fv1[2] << ")\n";
+ std::cout << " fv2=(" << fv2[0] << "," << fv2[1] << "," << fv2[2] << ")\n";
+ }
+ if (isect_ray_tri_epsilon_v3(
+ ray->origin, ray->direction, fv0, fv1, fv2, &dist, NULL, FLT_EPSILON)) {
+ /* Count parity as +1 if ray is in the same direction as tri's normal,
+ * and -1 if the directions are opposite. */
+ double3 o_db{double(ray->origin[0]), double(ray->origin[1]), double(ray->origin[2])};
+ int parity = orient3d(tri.vert[0]->co, tri.vert[1]->co, tri.vert[2]->co, o_db);
+ if (dbg_level > 0) {
+ std::cout << "origin at " << o_db << ", parity = " << parity << "\n";
+ }
+ data->hit_parity[shape] += parity;
}
- return gwn;
}
/**
- * Return true if point \a testp is inside the volume implied by the
- * faces for which the shape_fn returns the value shape.
- * If \a high_confidence is true then we want a higher degree
- * of "insideness" than if it is false.
+ * Test the triangle with index \a t_index to see which shapes it is inside,
+ * and fill in \a in_shape with a confidence value between 0 and 1 that says
+ * how likely we think it is that it is inside.
+ * This is done by casting some rays from just on the positive side of a test
+ * face in various directions and summing the parity of crossing faces of each face.
+ *
+ * \param tree: Contains all the triangles of \a tm and can be used for fast ray-casting.
*/
-static bool point_is_inside_shape(const IMesh &tm,
- std::function<int(int)> shape_fn,
- const double3 &testp,
- int shape,
- bool high_confidence)
+static void test_tri_inside_shapes(const IMesh &tm,
+ std::function<int(int)> shape_fn,
+ int nshapes,
+ int test_t_index,
+ BVHTree *tree,
+ Array<float> &in_shape)
{
- double gwn = generalized_winding_number(tm, shape_fn, testp, shape);
- /* Due to floating point error, an outside point should get a value
- * of zero for gwn, but may have a very slightly positive value instead.
- * It is not important to get this epsilon very small, because practical
- * cases of interest will have gwn at least 0.2 if it is not zero. */
- if (high_confidence) {
- return (gwn > 0.9);
+ const int dbg_level = 0;
+ if (dbg_level > 0) {
+ std::cout << "test_point_inside_shapes, t_index = " << test_t_index << "\n";
+ }
+ Face &tri_test = *tm.face(test_t_index);
+ int shape = shape_fn(tri_test.orig);
+ if (shape == -1) {
+ in_shape.fill(0.0f);
+ return;
+ }
+ double3 test_point = calc_point_inside_tri_db(tri_test);
+ /* Offset the test point a tiny bit in the tri_test normal direction. */
+ tri_test.populate_plane(false);
+ double3 norm = tri_test.plane->norm.normalized();
+ const double offset_amount = 1e-5;
+ double3 offset_test_point = test_point + offset_amount * norm;
+ if (dbg_level > 0) {
+ std::cout << "test tri is in shape " << shape << "\n";
+ std::cout << "test point = " << test_point << "\n";
+ std::cout << "offset_test_point = " << offset_test_point << "\n";
+ }
+ /* Try six test rays almost along orthogonal axes.
+ * Perturb their directions slightly to make it less likely to hit a seam.
+ * Ray-cast assumes they have unit length, so use r1 near 1 and
+ * ra near 0.5, and rb near .01, but normalized so `sqrt(r1^2 + ra^2 + rb^2) == 1`. */
+ constexpr int num_rays = 6;
+ constexpr float r1 = 0.9987025295199663f;
+ constexpr float ra = 0.04993512647599832f;
+ constexpr float rb = 0.009987025295199663f;
+ const float test_rays[num_rays][3] = {
+ {r1, ra, rb}, {-r1, -ra, -rb}, {rb, r1, ra}, {-rb, -r1, -ra}, {ra, rb, r1}, {-ra, -rb, -r1}};
+ InsideShapeTestData data(tm, shape_fn, nshapes);
+ data.hit_parity = Array<int>(nshapes, 0);
+ Array<int> count_insides(nshapes, 0);
+ const float co[3] = {
+ float(offset_test_point[0]), float(offset_test_point[1]), float(offset_test_point[2])};
+ for (int i = 0; i < num_rays; ++i) {
+ if (dbg_level > 0) {
+ std::cout << "shoot ray " << i << "(" << test_rays[i][0] << "," << test_rays[i][1] << ","
+ << test_rays[i][2] << ")\n";
+ }
+ BLI_bvhtree_ray_cast_all(tree, co, test_rays[i], 0.0f, FLT_MAX, inside_shape_callback, &data);
+ if (dbg_level > 0) {
+ std::cout << "ray " << i << " result:";
+ for (int j = 0; j < nshapes; ++j) {
+ std::cout << " " << data.hit_parity[j];
+ }
+ std::cout << "\n";
+ }
+ for (int j = 0; j < nshapes; ++j) {
+ if (j != shape && data.hit_parity[j] > 0) {
+ ++count_insides[j];
+ }
+ }
+ data.hit_parity.fill(0);
+ }
+ for (int j = 0; j < nshapes; ++j) {
+ if (j == shape) {
+ in_shape[j] = 1.0f; /* Let's say a shape is always inside itself. */
+ }
+ else {
+ in_shape[j] = float(count_insides[j]) / float(num_rays);
+ }
+ if (dbg_level > 0) {
+ std::cout << "shape " << j << " inside = " << in_shape[j] << "\n";
+ }
}
-
- return (gwn > 0.01);
}
/**
- * Use the Generalized Winding Number method for deciding if a patch of the
+ * Use the RayCast method for deciding if a triangle of the
* mesh is supposed to be included or excluded in the boolean result,
* and return the mesh that is the boolean result.
+ * The reason this is done on a triangle-by-triangle basis is that
+ * when the input is not PWN, some patches can be both inside and outside
+ * some shapes (e.g., a plane cutting through Suzanne's open eyes).
*/
-static IMesh gwn_boolean(const IMesh &tm,
- BoolOpType op,
- int nshapes,
- std::function<int(int)> shape_fn,
- const PatchesInfo &pinfo,
- IMeshArena *arena)
+static IMesh raycast_boolean(const IMesh &tm,
+ BoolOpType op,
+ int nshapes,
+ std::function<int(int)> shape_fn,
+ IMeshArena *arena)
{
constexpr int dbg_level = 0;
if (dbg_level > 0) {
- std::cout << "GWN_BOOLEAN\n";
+ std::cout << "RAYCAST_BOOLEAN\n";
}
IMesh ans;
+
+ /* Build a BVH tree of tm's triangles.
+ * We could possibly reuse the BVH tree(s) build in TriOverlaps in
+ * the mesh intersect function. A future TODO. */
+ BVHTree *tree = BLI_bvhtree_new(tm.face_size(), FLT_EPSILON, 8, 8);
+ for (int i : tm.face_index_range()) {
+ const Face *f = tm.face(i);
+ float t_cos[9];
+ for (int j = 0; j < 3; ++j) {
+ const Vert *v = f->vert[j];
+ for (int k = 0; k < 3; ++k) {
+ t_cos[3 * j + k] = float(v->co[k]);
+ }
+ }
+ BLI_bvhtree_insert(tree, i, t_cos, 3);
+ }
+ BLI_bvhtree_balance(tree);
+
Vector<Face *> out_faces;
out_faces.reserve(tm.face_size());
+ Array<float> in_shape(nshapes, 0);
Array<int> winding(nshapes, 0);
- for (int p : pinfo.index_range()) {
- const Patch &patch = pinfo.patch(p);
- /* For test triangle, choose one in the middle of patch list
- * as the ones near the beginning may be very near other patches. */
- int test_t_index = patch.tri(patch.tot_tri() / 2);
- Face &tri_test = *tm.face(test_t_index);
- /* Assume all triangles in a patch are in the same shape. */
- int shape = shape_fn(tri_test.orig);
+ for (int t : tm.face_index_range()) {
+ Face &tri = *tm.face(t);
+ int shape = shape_fn(tri.orig);
if (dbg_level > 0) {
- std::cout << "process patch " << p << " = " << patch << "\n";
- std::cout << "test tri = " << test_t_index << " = " << &tri_test << "\n";
+ std::cout << "process triangle " << t << " = " << &tri << "\n";
std::cout << "shape = " << shape << "\n";
}
- if (shape == -1) {
- continue;
- }
- mpq3 test_point = calc_point_inside_tri(tri_test);
- double3 test_point_db(test_point[0].get_d(), test_point[1].get_d(), test_point[2].get_d());
- if (dbg_level > 0) {
- std::cout << "test point = " << test_point_db << "\n";
- }
+ test_tri_inside_shapes(tm, shape_fn, nshapes, t, tree, in_shape);
for (int other_shape = 0; other_shape < nshapes; ++other_shape) {
if (other_shape == shape) {
continue;
}
- /* The point_is_inside_shape function has to approximate if the other
- * shape is not PWN. For most operations, even a hint of being inside
+ /* The in_shape array has a confidence value for "insideness".
+ * For most operations, even a hint of being inside
* gives good results, but when shape is a cutter in a Difference
* operation, we want to be pretty sure that the point is inside other_shape.
* E.g., T75827.
*/
bool need_high_confidence = (op == BoolOpType::Difference) && (shape != 0);
- bool inside = point_is_inside_shape(
- tm, shape_fn, test_point_db, other_shape, need_high_confidence);
+ bool inside = in_shape[other_shape] >= (need_high_confidence ? 0.5f : 0.1f);
if (dbg_level > 0) {
std::cout << "test point is " << (inside ? "inside" : "outside") << " other_shape "
<< other_shape << "\n";
@@ -2503,29 +2565,26 @@ static IMesh gwn_boolean(const IMesh &tm,
std::cout << winding[i] << " ";
}
std::cout << "\niv0=" << in_output_volume_0 << ", iv1=" << in_output_volume_1 << "\n";
- std::cout << "result for patch " << p << ": remove=" << do_remove << ", flip=" << do_flip
+ std::cout << "result for tri " << t << ": remove=" << do_remove << ", flip=" << do_flip
<< "\n";
}
if (!do_remove) {
- for (int t : patch.tris()) {
- Face *f = tm.face(t);
- if (!do_flip) {
- out_faces.append(f);
- }
- else {
- Face &tri = *f;
- /* We need flipped version of f. */
- Array<const Vert *> flipped_vs = {tri[0], tri[2], tri[1]};
- Array<int> flipped_e_origs = {tri.edge_orig[2], tri.edge_orig[1], tri.edge_orig[0]};
- Array<bool> flipped_is_intersect = {
- tri.is_intersect[2], tri.is_intersect[1], tri.is_intersect[0]};
- Face *flipped_f = arena->add_face(
- flipped_vs, f->orig, flipped_e_origs, flipped_is_intersect);
- out_faces.append(flipped_f);
- }
+ if (!do_flip) {
+ out_faces.append(&tri);
+ }
+ else {
+ /* We need flipped version of tri. */
+ Array<const Vert *> flipped_vs = {tri[0], tri[2], tri[1]};
+ Array<int> flipped_e_origs = {tri.edge_orig[2], tri.edge_orig[1], tri.edge_orig[0]};
+ Array<bool> flipped_is_intersect = {
+ tri.is_intersect[2], tri.is_intersect[1], tri.is_intersect[0]};
+ Face *flipped_f = arena->add_face(
+ flipped_vs, tri.orig, flipped_e_origs, flipped_is_intersect);
+ out_faces.append(flipped_f);
}
}
}
+ BLI_bvhtree_free(tree);
ans.set_faces(out_faces);
return ans;
}
@@ -3109,6 +3168,14 @@ static Vector<Face *> merge_tris_for_face(Vector<int> tris,
return ans;
}
+static bool approx_in_line(const double3 &a, const double3 &b, const double3 &c)
+{
+ double3 vec1 = b - a;
+ double3 vec2 = c - b;
+ double cos_ang = double3::dot(vec1.normalized(), vec2.normalized());
+ return fabs(cos_ang - 1.0) < 1e-4;
+}
+
/**
* Return an array, paralleling imesh_out.vert, saying which vertices can be dissolved.
* A vertex v can be dissolved if (a) it is not an input vertex; (b) it has valence 2;
@@ -3161,8 +3228,11 @@ static Array<bool> find_dissolve_verts(IMesh &imesh_out, int *r_count_dissolve)
const std::pair<const Vert *, const Vert *> &nbrs = neighbors[v_out];
if (nbrs.first != nullptr) {
BLI_assert(nbrs.second != nullptr);
- dissolve[v_out] = true;
- ++count;
+ const Vert *v_v_out = imesh_out.vert(v_out);
+ if (approx_in_line(nbrs.first->co, v_v_out->co, nbrs.second->co)) {
+ dissolve[v_out] = true;
+ ++count;
+ }
}
}
}
@@ -3339,30 +3409,27 @@ IMesh boolean_trimesh(IMesh &tm_in,
double topo_time = PIL_check_seconds_timer();
std::cout << " topology built, time = " << topo_time - intersect_time << "\n";
# endif
- PatchesInfo pinfo = find_patches(tm_si, tm_si_topo);
+ bool pwn = is_pwn(tm_si, tm_si_topo);
# ifdef PERFDEBUG
- double patch_time = PIL_check_seconds_timer();
- std::cout << " patches found, time = " << patch_time - topo_time << "\n";
+ double pwn_time = PIL_check_seconds_timer();
+ std::cout << " pwn checked, time = " << pwn_time - topo_time << "\n";
# endif
IMesh tm_out;
- if (!is_pwn(tm_si, tm_si_topo)) {
-# ifdef PERFDEBUG
- double pwn_check_time = PIL_check_seconds_timer();
- std::cout << " pwn checked (not pwn), time = " << pwn_check_time - patch_time << "\n";
-# endif
+ if (!pwn) {
if (dbg_level > 0) {
- std::cout << "Input is not PWN, using gwn method\n";
+ std::cout << "Input is not PWN, using raycast method\n";
}
- tm_out = gwn_boolean(tm_si, op, nshapes, shape_fn, pinfo, arena);
+ tm_out = raycast_boolean(tm_si, op, nshapes, shape_fn, arena);
# ifdef PERFDEBUG
- double gwn_time = PIL_check_seconds_timer();
- std::cout << " gwn, time = " << gwn_time - pwn_check_time << "\n";
+ double raycast_time = PIL_check_seconds_timer();
+ std::cout << " raycast_boolean done, time = " << raycast_time - pwn_time << "\n";
# endif
}
else {
+ PatchesInfo pinfo = find_patches(tm_si, tm_si_topo);
# ifdef PERFDEBUG
- double pwn_time = PIL_check_seconds_timer();
- std::cout << " pwn checked (ok), time = " << pwn_time - patch_time << "\n";
+ double patch_time = PIL_check_seconds_timer();
+ std::cout << " patches found, time = " << patch_time - pwn_time << "\n";
# endif
CellsInfo cinfo = find_cells(tm_si, tm_si_topo, pinfo);
if (dbg_level > 0) {
diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc
index 85a6ab42013..b2b8dd4e900 100644
--- a/source/blender/blenlib/intern/mesh_intersect.cc
+++ b/source/blender/blenlib/intern/mesh_intersect.cc
@@ -1055,25 +1055,22 @@ static std::ostream &operator<<(std::ostream &os, const CoplanarClusterInfo &cli
enum ITT_value_kind { INONE, IPOINT, ISEGMENT, ICOPLANAR };
struct ITT_value {
- mpq3 p1; /* Only relevant for IPOINT and ISEGMENT kind. */
- mpq3 p2; /* Only relevant for ISEGMENT kind. */
- int t_source; /* Index of the source triangle that intersected the target one. */
- enum ITT_value_kind kind;
+ mpq3 p1; /* Only relevant for IPOINT and ISEGMENT kind. */
+ mpq3 p2; /* Only relevant for ISEGMENT kind. */
+ int t_source = -1; /* Index of the source triangle that intersected the target one. */
+ enum ITT_value_kind kind = INONE;
- ITT_value() : t_source(-1), kind(INONE)
- {
- }
- ITT_value(ITT_value_kind k) : t_source(-1), kind(k)
+ ITT_value() = default;
+ explicit ITT_value(ITT_value_kind k) : kind(k)
{
}
ITT_value(ITT_value_kind k, int tsrc) : t_source(tsrc), kind(k)
{
}
- ITT_value(ITT_value_kind k, const mpq3 &p1) : p1(p1), t_source(-1), kind(k)
+ ITT_value(ITT_value_kind k, const mpq3 &p1) : p1(p1), kind(k)
{
}
- ITT_value(ITT_value_kind k, const mpq3 &p1, const mpq3 &p2)
- : p1(p1), p2(p2), t_source(-1), kind(k)
+ ITT_value(ITT_value_kind k, const mpq3 &p1, const mpq3 &p2) : p1(p1), p2(p2), kind(k)
{
}
ITT_value(const ITT_value &other)
@@ -1385,7 +1382,7 @@ static ITT_value itt_canon2(const mpq3 &p1,
return ITT_value(ISEGMENT, intersect_1, intersect_2);
}
-/* Helper function for intersect_tri_tri. Args have been canonicalized for triangle 1. */
+/* Helper function for intersect_tri_tri. Arguments have been canonicalized for triangle 1. */
static ITT_value itt_canon1(const mpq3 &p1,
const mpq3 &q1,
@@ -2026,7 +2023,7 @@ class TriOverlaps {
if (dbg_level > 0) {
std::cout << "TriOverlaps construction\n";
}
- /* Tree type is 8 => octtree; axis = 6 => using XYZ axes only. */
+ /* Tree type is 8 => octree; axis = 6 => using XYZ axes only. */
tree_ = BLI_bvhtree_new(tm.face_size(), FLT_EPSILON, 8, 6);
/* In the common case of a binary boolean and no self intersection in
* each shape, we will use two trees and simple bounding box overlap. */
@@ -2378,7 +2375,7 @@ static CDT_data calc_cluster_subdivided(const CoplanarClusterInfo &clinfo,
}
}
}
- /* Use CDT to subdivide the cluster triangles and the points and segs in itts. */
+ /* Use CDT to subdivide the cluster triangles and the points and segments in itts. */
CDT_data cd_data = prepare_cdt_input_for_cluster(tm, clinfo, c, itts);
do_cdt(cd_data);
return cd_data;
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 5636ffafb6a..b076d0f09c1 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -459,7 +459,7 @@ static wchar_t *next_slash(wchar_t *path)
return slash;
}
-/* adds a slash if the unc path points sto a share */
+/* Adds a slash if the UNC path points to a share. */
static void BLI_path_add_slash_to_share(wchar_t *uncpath)
{
wchar_t *slash_after_server = next_slash(uncpath + 2);
@@ -1279,7 +1279,7 @@ void BLI_setenv(const char *env, const char *val)
uputenv(env, val);
#else
- /* linux/osx/bsd */
+ /* Linux/macOS/BSD */
if (val) {
setenv(env, val, 1);
}
@@ -1375,7 +1375,7 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir, c
}
}
else {
- return; /* string is NULL, probably shouldnt happen but return anyway */
+ return; /* string is NULL, probably shouldn't happen but return anyway */
}
/* Resolve relative references */
@@ -1650,7 +1650,7 @@ bool BLI_path_filename_ensure(char *filepath, size_t maxlen, const char *filenam
* - Wont create any directories.
* - Doesn't use CWD, or deal with relative paths.
* - Only fill's in \a dir and \a file when they are non NULL.
- * */
+ */
void BLI_split_dirfile(
const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
{
diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c
index fe9fa514e08..dadef979b09 100644
--- a/source/blender/blenlib/intern/polyfill_2d.c
+++ b/source/blender/blenlib/intern/polyfill_2d.c
@@ -253,7 +253,7 @@ static uint kdtree2d_balance_recursive(
return 0 + ofs;
}
- /* quicksort style sorting around median */
+ /* Quick-sort style sorting around median. */
neg = 0;
pos = totnode - 1;
median = totnode / 2;
@@ -284,7 +284,7 @@ static uint kdtree2d_balance_recursive(
}
}
- /* set node and sort subnodes */
+ /* Set node and sort sub-nodes. */
node = &nodes[median];
node->axis = axis;
axis = !axis;
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 2a520516418..8c9a229860e 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -526,10 +526,10 @@ static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int fl
if (eve->poly_nr == nr) {
if (eve->f != SF_VERT_ZERO_LEN) {
verts++;
- eve->f = SF_VERT_NEW; /* flag for connectedges later on */
+ eve->f = SF_VERT_NEW; /* Flag for connect edges later on. */
sc->vert = eve;
sc->edge_first = sc->edge_last = NULL;
- /* Note, debug print only will work for curve polyfill, union is in use for mesh */
+ /* Note, debug print only will work for curve poly-fill, union is in use for mesh. */
/* if (even->tmp.v == NULL) eve->tmp.u = verts; */
sc++;
}
@@ -609,7 +609,7 @@ static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int fl
sc = scdata;
for (a = 0; a < verts; a++) {
/* printf("VERTEX %d index %d\n", a, sc->vert->tmp.u); */
- /* set connectflags */
+ /* Set connect-flags. */
for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
eed_next = ed1->next;
if (ed1->v1->edge_tot == 1 || ed1->v2->edge_tot == 1) {
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index b49239547c2..ec0f8659395 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -244,7 +244,7 @@ static bool scanfill_preprocess_self_isect(ScanFillContext *sf_ctx,
continue;
}
- /* maintain coorect terminating edge */
+ /* Maintain correct terminating edge. */
if (pi->edge_last == eed) {
pi->edge_last = NULL;
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index d1e133318ba..bb00755e901 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -30,7 +30,7 @@
#include <sys/stat.h>
#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__HAIKU__)
-/* Other modern unix os's should probably use this also */
+/* Other modern unix OS's should probably use this also. */
# include <sys/statvfs.h>
# define USE_STATFS_STATVFS
#endif
@@ -113,7 +113,7 @@ double BLI_dir_free_space(const char *dir)
char tmp[4];
tmp[0] = '\\';
- tmp[1] = 0; /* Just a failsafe */
+ tmp[1] = 0; /* Just a fail-safe. */
if (ELEM(dir[0] == '/', '\\')) {
tmp[0] = '\\';
tmp[1] = 0;
diff --git a/source/blender/blenlib/intern/string_search.cc b/source/blender/blenlib/intern/string_search.cc
index a45909f92d8..a09aa7a4bc2 100644
--- a/source/blender/blenlib/intern/string_search.cc
+++ b/source/blender/blenlib/intern/string_search.cc
@@ -447,7 +447,7 @@ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_d
for (const int score : result_indices_by_score.keys()) {
found_scores.append(score);
}
- std::sort(found_scores.begin(), found_scores.end(), std::greater<int>());
+ std::sort(found_scores.begin(), found_scores.end(), std::greater<>());
/* Add results to output vector in correct order. First come the results with the best match
* score. Results with the same score are in the order they have been added to the search. */
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index a637a5f24e6..7aa5930b4ad 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -225,8 +225,7 @@ int BLI_utf8_invalid_strip(char *str, size_t length)
return tot;
}
-/* compatible with BLI_strncpy, but esnure no partial utf8 chars */
-
+/** Compatible with #BLI_strncpy, but ensure no partial UTF8 chars. */
#define BLI_STR_UTF8_CPY(dst, src, maxncpy) \
{ \
size_t utf8_size; \
diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c
index 8e3d489fbb3..e32f310549c 100644
--- a/source/blender/blenlib/intern/system.c
+++ b/source/blender/blenlib/intern/system.c
@@ -71,7 +71,7 @@ int BLI_cpu_support_sse2(void)
#endif
}
-/* Windows stackwalk lives in system_win32.c */
+/* Windows stack-walk lives in system_win32.c */
#if !defined(_MSC_VER)
/**
* Write a backtrace into a file for systems which support it.
diff --git a/source/blender/blenlib/intern/system_win32.c b/source/blender/blenlib/intern/system_win32.c
index be2195d679d..7572936592e 100644
--- a/source/blender/blenlib/intern/system_win32.c
+++ b/source/blender/blenlib/intern/system_win32.c
@@ -386,7 +386,6 @@ void BLI_system_backtrace(FILE *fp)
bli_windows_system_backtrace_threads(fp);
}
bli_windows_system_backtrace_modules(fp);
- fputc(0, fp); /* Give our selves a nice zero terminator for later on */
}
void BLI_windows_handle_exception(EXCEPTION_POINTERS *exception)
diff --git a/source/blender/blenlib/intern/task_graph.cc b/source/blender/blenlib/intern/task_graph.cc
index 4f112c5b2c8..32450c16630 100644
--- a/source/blender/blenlib/intern/task_graph.cc
+++ b/source/blender/blenlib/intern/task_graph.cc
@@ -28,10 +28,7 @@
#include <vector>
#ifdef WITH_TBB
-/* Quiet top level deprecation message, unrelated to API usage here. */
-# define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
# include <tbb/flow_graph.h>
-# include <tbb/tbb.h>
#endif
/* Task Graph */
@@ -70,7 +67,7 @@ struct TaskNode {
#ifdef WITH_TBB
tbb_node(task_graph->tbb_graph,
tbb::flow::unlimited,
- std::bind(&TaskNode::run, this, std::placeholders::_1)),
+ [&](const tbb::flow::continue_msg input) { run(input); }),
#endif
run_func(run_func),
task_data(task_data),
diff --git a/source/blender/blenlib/intern/task_pool.cc b/source/blender/blenlib/intern/task_pool.cc
index 10f15f8749c..00ba659a9c8 100644
--- a/source/blender/blenlib/intern/task_pool.cc
+++ b/source/blender/blenlib/intern/task_pool.cc
@@ -34,9 +34,9 @@
#include "BLI_threads.h"
#ifdef WITH_TBB
-/* Quiet top level deprecation message, unrelated to API usage here. */
-# define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
-# include <tbb/tbb.h>
+# include <tbb/blocked_range.h>
+# include <tbb/task_arena.h>
+# include <tbb/task_group.h>
#endif
/* Task
diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc
index c2498de1af8..a27241e91dd 100644
--- a/source/blender/blenlib/intern/task_range.cc
+++ b/source/blender/blenlib/intern/task_range.cc
@@ -32,9 +32,10 @@
#include "atomic_ops.h"
#ifdef WITH_TBB
-/* Quiet top level deprecation message, unrelated to API usage here. */
-# define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
-# include <tbb/tbb.h>
+# include <tbb/blocked_range.h>
+# include <tbb/enumerable_thread_specific.h>
+# include <tbb/parallel_for.h>
+# include <tbb/parallel_reduce.h>
#endif
#ifdef WITH_TBB
diff --git a/source/blender/blenlib/intern/task_scheduler.cc b/source/blender/blenlib/intern/task_scheduler.cc
index b0245da0385..b22334a5676 100644
--- a/source/blender/blenlib/intern/task_scheduler.cc
+++ b/source/blender/blenlib/intern/task_scheduler.cc
@@ -26,10 +26,10 @@
#include "BLI_threads.h"
#ifdef WITH_TBB
-/* Quiet top level deprecation message, unrelated to API usage here. */
-# define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
-# include <tbb/tbb.h>
+/* Need to include at least one header to get the version define. */
+# include <tbb/blocked_range.h>
# if TBB_INTERFACE_VERSION_MAJOR >= 10
+# include <tbb/global_control.h>
# define WITH_TBB_GLOBAL_CONTROL
# endif
#endif
diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc
index 0b88cf53442..35097013439 100644
--- a/source/blender/blenlib/intern/threads.cc
+++ b/source/blender/blenlib/intern/threads.cc
@@ -289,9 +289,8 @@ void BLI_threadpool_clear(ListBase *threadbase)
void BLI_threadpool_end(ListBase *threadbase)
{
- /* only needed if there's actually some stuff to end
- * this way we don't end up decrementing thread_levels on an empty threadbase
- * */
+ /* Only needed if there's actually some stuff to end
+ * this way we don't end up decrementing thread_levels on an empty `threadbase`. */
if (threadbase == nullptr || BLI_listbase_is_empty(threadbase)) {
return;
}
@@ -469,7 +468,7 @@ void BLI_spin_lock(SpinLock *spin)
#elif defined(_MSC_VER)
while (InterlockedExchangeAcquire(spin, 1)) {
while (*spin) {
- /* Spin-lock hint for processors with hyperthreading. */
+ /* Spin-lock hint for processors with hyper-threading. */
YieldProcessor();
}
}
diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c
index eac01a0e2aa..c0c895654e3 100644
--- a/source/blender/blenlib/intern/voxel.c
+++ b/source/blender/blenlib/intern/voxel.c
@@ -54,12 +54,14 @@ BLI_INLINE int FLOORI(float x)
return ((x >= 0.0f) || (float)r == x) ? r : (r - 1);
}
-/* clamp function, cannot use the CLAMPIS macro,
+/**
+ * clamp function, cannot use the CLAMPIS macro,
* it sometimes returns unwanted results apparently related to
- * gcc optimization flag -fstrict-overflow which is enabled at -O2
+ * gcc optimization flag `-fstrict-overflow` which is enabled at `-O2`
*
* this causes the test (x + 2) < 0 with int x == 2147483647 to return false (x being an integer,
- * x + 2 should wrap around to -2147483647 so the test < 0 should return true, which it doesn't) */
+ * x + 2 should wrap around to -2147483647 so the test < 0 should return true, which it doesn't).
+ */
BLI_INLINE int64_t _clamp(int a, int b, int c)
{
return (a < b) ? b : ((a > c) ? c : a);
diff --git a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
index 487afc095f9..d00e8bf55fd 100644
--- a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
@@ -1661,10 +1661,10 @@ void rand_delaunay_test(int test_kind,
}
}
for (int i = 0; i < size; ++i) {
- /* Horizontal edges: connect p(i,0) to p(i,size-1). */
+ /* Horizontal edges: connect `p(i,0)` to `p(i,size-1)`. */
in.edge[i].first = i * size;
in.edge[i].second = i * size + size - 1;
- /* Vertical edges: conntect p(0,i) to p(size-1,i). */
+ /* Vertical edges: connect `p(0,i)` to `p(size-1,i)`. */
in.edge[size + i].first = i;
in.edge[size + i].second = (size - 1) * size + i;
}
@@ -1695,7 +1695,7 @@ void rand_delaunay_test(int test_kind,
in.vert[ib][1] = T(sin(angle2));
in.vert[ic][0] = T((param * cos(angle3)));
in.vert[ic][1] = T((param * sin(angle3)));
- /* Put the coordinates in ccw order. */
+ /* Put the coordinates in CCW order. */
in.face[i].append(ia);
int orient = orient2d(in.vert[ia], in.vert[ib], in.vert[ic]);
if (orient >= 0) {
diff --git a/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc b/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
index 3c9d12c7178..8bf5dd0bc9b 100644
--- a/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
@@ -291,7 +291,7 @@ static void test_polyfill_template_main(const char *id,
(void)0
/* -------------------------------------------------------------------- */
-/* visualisation functions (not needed for testing) */
+/* visualization functions (not needed for testing) */
#ifdef USE_OBJ_PREVIEW
static void polyfill_to_obj(const char *id,
@@ -491,7 +491,7 @@ TEST(polyfill2d, Spiral)
TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
}
-/* Test case from http:# www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml */
+/* Test case from http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml */
TEST(polyfill2d, TestFlipCode)
{
const float poly[][2] = {
@@ -561,7 +561,7 @@ TEST(polyfill2d, SelfOverlap)
TEST_POLYFILL_TEMPLATE_STATIC(poly, true);
}
-/* Test case from http:# www.davdata.nl/math/polygons.html */
+/* Test case from http://www.davdata.nl/math/polygons.html */
TEST(polyfill2d, TestDavData)
{
const float poly[][2] = {
@@ -573,7 +573,7 @@ TEST(polyfill2d, TestDavData)
TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
}
-/* Issue 815, http:# code.google.com/p/libgdx/issues/detail?id=815 */
+/* Issue 815, http://code.google.com/p/libgdx/issues/detail?id=815 */
TEST(polyfill2d, Issue815)
{
const float poly[][2] = {
@@ -589,7 +589,7 @@ TEST(polyfill2d, Issue815)
TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
}
-/* Issue 207, comment #1, http:# code.google.com/p/libgdx/issues/detail?id=207#c1 */
+/* Issue 207, comment #1, http://code.google.com/p/libgdx/issues/detail?id=207#c1 */
TEST(polyfill2d, Issue207_1)
{
const float poly[][2] = {
@@ -608,8 +608,8 @@ TEST(polyfill2d, Issue207_1)
TEST_POLYFILL_TEMPLATE_STATIC(poly, true);
}
-/* Issue 207, comment #11, http:# code.google.com/p/libgdx/issues/detail?id=207#c11 */
-/* Also on issue 1081, http:# code.google.com/p/libgdx/issues/detail?id=1081 */
+/* Issue 207, comment #11, http://code.google.com/p/libgdx/issues/detail?id=207#c11 */
+/* Also on issue 1081, http://code.google.com/p/libgdx/issues/detail?id=1081 */
TEST(polyfill2d, Issue207_11)
{
const float poly[][2] = {
@@ -628,7 +628,7 @@ TEST(polyfill2d, Issue207_11)
TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
}
-/* Issue 1407, http:# code.google.com/p/libgdx/issues/detail?id=1407 */
+/* Issue 1407, http://code.google.com/p/libgdx/issues/detail?id=1407 */
TEST(polyfill2d, Issue1407)
{
const float poly[][2] = {
@@ -640,7 +640,7 @@ TEST(polyfill2d, Issue1407)
TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
}
-/* Issue 1407, http:# code.google.com/p/libgdx/issues/detail?id=1407, */
+/* Issue 1407, http://code.google.com/p/libgdx/issues/detail?id=1407, */
/* with an additional point to show what is happening. */
TEST(polyfill2d, Issue1407_pt)
{
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 1d7c5d8a1d3..c7f02de21ea 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -84,8 +84,8 @@ struct BlendFileReadParams {
uint skip_flags : 3; /* eBLOReadSkip */
uint is_startup : 1;
- /** Whether we are reading the memfile for an undo (< 0) or a redo (> 0). */
- int undo_direction : 2;
+ /** Whether we are reading the memfile for an undo or a redo. */
+ int undo_direction; /* eUndoStepDir */
};
/* skip reading some data-block types (may want to skip screen data too). */
@@ -129,11 +129,13 @@ BlendHandle *BLO_blendhandle_from_memory(const void *mem, int memsize);
struct LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh,
int ofblocktype,
- int *tot_names);
+
+ const bool use_assets_only,
+ int *r_tot_names);
struct LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
int ofblocktype,
- int *tot_info_items);
-struct LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *tot_prev);
+ int *r_tot_info_items);
+struct LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_tot_prev);
struct LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh);
void BLO_blendhandle_close(BlendHandle *bh);
diff --git a/source/blender/blenloader/intern/blend_validate.c b/source/blender/blenloader/intern/blend_validate.c
index c281e2fa643..7261db5d3a6 100644
--- a/source/blender/blenloader/intern/blend_validate.c
+++ b/source/blender/blenloader/intern/blend_validate.c
@@ -23,7 +23,7 @@
* \note Does not *fix* anything, only reports found errors.
*/
-#include <string.h> /* for strrchr strncmp strstr */
+#include <string.h> /* for #strrchr #strncmp #strstr */
#include "BLI_utildefines.h"
@@ -112,7 +112,7 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports)
}
int totnames = 0;
- LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), &totnames);
+ LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), false, &totnames);
for (; id != NULL; id = id->next) {
if (id->lib == NULL) {
is_valid = false;
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 296480fc2e4..19033ba9bf1 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -135,9 +135,13 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
* \param bh: The blendhandle to access.
* \param ofblocktype: The type of names to get.
* \param tot_names: The length of the returned list.
+ * \param use_assets_only: Only list IDs marked as assets.
* \return A BLI_linklist of strings. The string links should be freed with #MEM_freeN().
*/
-LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, int *tot_names)
+LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh,
+ int ofblocktype,
+ const bool use_assets_only,
+ int *r_tot_names)
{
FileData *fd = (FileData *)bh;
LinkNode *names = NULL;
@@ -147,6 +151,9 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype,
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) {
+ continue;
+ }
BLI_linklist_prepend(&names, BLI_strdup(idname + 2));
tot++;
@@ -156,7 +163,7 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype,
}
}
- *tot_names = tot;
+ *r_tot_names = tot;
return names;
}
@@ -170,7 +177,9 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype,
* \return A BLI_linklist of BLODataBlockInfo *. The links and #BLODataBlockInfo.asset_data should
* be freed with MEM_freeN.
*/
-LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh, int ofblocktype, int *tot_info_items)
+LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
+ int ofblocktype,
+ int *r_tot_info_items)
{
FileData *fd = (FileData *)bh;
LinkNode *infos = NULL;
@@ -201,7 +210,7 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh, int ofblocktype, i
}
}
- *tot_info_items = tot;
+ *r_tot_info_items = tot;
return infos;
}
@@ -211,10 +220,10 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh, int ofblocktype, i
*
* \param bh: The blendhandle to access.
* \param ofblocktype: The type of names to get.
- * \param tot_prev: The length of the returned list.
+ * \param r_tot_prev: The length of the returned list.
* \return A BLI_linklist of PreviewImage. The PreviewImage links should be freed with malloc.
*/
-LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *tot_prev)
+LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_tot_prev)
{
FileData *fd = (FileData *)bh;
LinkNode *previews = NULL;
@@ -236,6 +245,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
case ID_OB: /* fall through */
case ID_GR: /* fall through */
case ID_SCE: /* fall through */
+ case ID_AC: /* fall through */
new_prv = MEM_callocN(sizeof(PreviewImage), "newpreview");
BLI_linklist_prepend(&previews, new_prv);
tot++;
@@ -294,7 +304,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
}
}
- *tot_prev = tot;
+ *r_tot_prev = tot;
return previews;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index b61abd4ed06..c90572a68a6 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -68,6 +68,7 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_mempool.h"
+#include "BLI_mmap.h"
#include "BLI_threads.h"
#include "BLT_translation.h"
@@ -93,6 +94,7 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "BKE_undo_system.h"
#include "BKE_workspace.h"
#include "DRW_engine.h"
@@ -1179,6 +1181,53 @@ static ssize_t fd_read_from_memory(FileData *filedata,
return readsize;
}
+/* Memory-mapped file reading.
+ * By using mmap(), we can map a file so that it can be treated like normal memory,
+ * meaning that we can just read from it with memcpy() etc.
+ * This avoids system call overhead and can significantly speed up file loading.
+ */
+
+static ssize_t fd_read_from_mmap(FileData *filedata,
+ void *buffer,
+ size_t size,
+ bool *UNUSED(r_is_memchunck_identical))
+{
+ /* don't read more bytes than there are available in the buffer */
+ size_t readsize = MIN2(size, (size_t)(filedata->buffersize - filedata->file_offset));
+
+ if (!BLI_mmap_read(filedata->mmap_file, buffer, filedata->file_offset, readsize)) {
+ return 0;
+ }
+
+ filedata->file_offset += readsize;
+
+ return readsize;
+}
+
+static off64_t fd_seek_from_mmap(FileData *filedata, off64_t offset, int whence)
+{
+ off64_t new_pos;
+ if (whence == SEEK_CUR) {
+ new_pos = filedata->file_offset + offset;
+ }
+ else if (whence == SEEK_SET) {
+ new_pos = offset;
+ }
+ else if (whence == SEEK_END) {
+ new_pos = filedata->buffersize + offset;
+ }
+ else {
+ return -1;
+ }
+
+ if (new_pos < 0 || new_pos > filedata->buffersize) {
+ return -1;
+ }
+
+ filedata->file_offset = new_pos;
+ return filedata->file_offset;
+}
+
/* MemFile reading. */
static ssize_t fd_read_from_memfile(FileData *filedata,
@@ -1246,12 +1295,12 @@ static ssize_t fd_read_from_memfile(FileData *filedata,
seek += readsize;
if (r_is_memchunck_identical != NULL) {
/* `is_identical` of current chunk represents whether it changed compared to previous undo
- * step. this is fine in redo case (filedata->undo_direction > 0), but not in undo case,
- * where we need an extra flag defined when saving the next (future) step after the one we
- * want to restore, as we are supposed to 'come from' that future undo step, and not the
- * one before current one. */
- *r_is_memchunck_identical &= filedata->undo_direction > 0 ? chunk->is_identical :
- chunk->is_identical_future;
+ * step. this is fine in redo case, but not in undo case, where we need an extra flag
+ * defined when saving the next (future) step after the one we want to restore, as we are
+ * supposed to 'come from' that future undo step, and not the one before current one. */
+ *r_is_memchunck_identical &= filedata->undo_direction == STEP_REDO ?
+ chunk->is_identical :
+ chunk->is_identical_future;
}
} while (totread < size);
@@ -1306,6 +1355,8 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
{
FileDataReadFn *read_fn = NULL;
FileDataSeekFn *seek_fn = NULL; /* Optional. */
+ size_t buffersize = 0;
+ BLI_mmap_file *mmap_file = NULL;
gzFile gzfile = (gzFile)Z_NULL;
@@ -1322,14 +1373,21 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
return NULL;
}
- BLI_lseek(file, 0, SEEK_SET);
-
/* Regular file. */
if (memcmp(header, "BLENDER", sizeof(header)) == 0) {
read_fn = fd_read_data_from_file;
seek_fn = fd_seek_data_from_file;
+
+ mmap_file = BLI_mmap_open(file);
+ if (mmap_file != NULL) {
+ read_fn = fd_read_from_mmap;
+ seek_fn = fd_seek_from_mmap;
+ buffersize = BLI_lseek(file, 0, SEEK_END);
+ }
}
+ BLI_lseek(file, 0, SEEK_SET);
+
/* Gzip file. */
errno = 0;
if ((read_fn == NULL) &&
@@ -1363,6 +1421,8 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
fd->read = read_fn;
fd->seek = seek_fn;
+ fd->mmap_file = mmap_file;
+ fd->buffersize = buffersize;
return fd;
}
@@ -1531,6 +1591,11 @@ void blo_filedata_free(FileData *fd)
fd->buffer = NULL;
}
+ if (fd->mmap_file) {
+ BLI_mmap_free(fd->mmap_file);
+ fd->mmap_file = NULL;
+ }
+
/* Free all BHeadN data blocks */
#ifndef NDEBUG
BLI_freelistN(&fd->bhead_list);
@@ -1718,25 +1783,25 @@ BlendThumbnail *BLO_thumbnail_from_file(const char *filepath)
/** \name Old/New Pointer Map
* \{ */
-/* only direct databocks */
+/* Only direct data-blocks. */
static void *newdataadr(FileData *fd, const void *adr)
{
return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
}
-/* only direct databocks */
+/* Only direct data-blocks. */
static void *newdataadr_no_us(FileData *fd, const void *adr)
{
return oldnewmap_lookup_and_inc(fd->datamap, adr, false);
}
-/* direct datablocks with global linking */
+/* Direct datablocks with global linking. */
void *blo_read_get_new_globaldata_address(FileData *fd, const void *adr)
{
return oldnewmap_lookup_and_inc(fd->globmap, adr, true);
}
-/* used to restore packed data after undo */
+/* Used to restore packed data after undo. */
static void *newpackedadr(FileData *fd, const void *adr)
{
if (fd->packedmap && adr) {
@@ -2336,11 +2401,12 @@ static int direct_link_id_restore_recalc(const FileData *fd,
/* Tags that were set between the target state and the current state,
* that we need to perform again. */
- if (fd->undo_direction < 0) {
+ if (fd->undo_direction == STEP_UNDO) {
/* Undo: tags from target to the current state. */
recalc |= id_current->recalc_up_to_undo_push;
}
else {
+ BLI_assert(fd->undo_direction == STEP_REDO);
/* Redo: tags from current to the target state. */
recalc |= id_target->recalc_up_to_undo_push;
}
@@ -3852,6 +3918,26 @@ static void lib_link_all(FileData *fd, Main *bmain)
}
FOREACH_MAIN_ID_END;
+#ifndef NDEBUG
+ /* Double check we do not have any 'need link' tag remaining, this should never be the case once
+ * this function has run. */
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ BLI_assert((id->tag & LIB_TAG_NEED_LINK) == 0);
+ }
+ FOREACH_MAIN_ID_END;
+#endif
+}
+
+/**
+ * Checks to perform after `lib_link_all`.
+ * Those operations cannot perform properly in a split bmain case, since some data from other
+ * bmain's (aka libraries) may not have been processed yet.
+ */
+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));
+
/* Check for possible cycles in scenes' 'set' background property. */
lib_link_scenes_check_set(bmain);
@@ -3862,15 +3948,6 @@ static void lib_link_all(FileData *fd, Main *bmain)
/* We have to rebuild that runtime information *after* all data-blocks have been properly linked.
*/
BKE_main_collections_parent_relations_rebuild(bmain);
-
-#ifndef NDEBUG
- /* Double check we do not have any 'need link' tag remaining, this should never be the case once
- * this function has run. */
- FOREACH_MAIN_ID_BEGIN (bmain, id) {
- BLI_assert((id->tag & LIB_TAG_NEED_LINK) == 0);
- }
- FOREACH_MAIN_ID_END;
-#endif
}
/** \} */
@@ -4093,6 +4170,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
blo_join_main(&mainlist);
lib_link_all(fd, bfd->main);
+ after_liblink_merged_bmain_process(bfd->main);
/* Skip in undo case. */
if (fd->memfile == NULL) {
@@ -5041,6 +5119,7 @@ static void library_link_end(Main *mainl,
mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
lib_link_all(*fd, mainvar);
+ after_liblink_merged_bmain_process(mainvar);
/* Some versioning code does expect some proper userrefcounting, e.g. in conversion from
* groups to collections... We could optimize out that first call when we are reading a
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index c724cc32051..e007d42b283 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -41,6 +41,7 @@ struct Object;
struct OldNewMap;
struct ReportList;
struct UserDef;
+struct BLI_mmap_file;
typedef struct IDNameLib_Map IDNameLib_Map;
@@ -83,13 +84,14 @@ typedef struct FileData {
/** Regular file reading. */
int filedes;
- /** Variables needed for reading from memory / stream. */
+ /** Variables needed for reading from memory / stream / memory-mapped files. */
const char *buffer;
+ struct BLI_mmap_file *mmap_file;
/** Variables needed for reading from memfile (undo). */
struct MemFile *memfile;
/** Whether we are undoing (< 0) or redoing (> 0), used to choose which 'unchanged' flag to use
* to detect unchanged data from memfile. */
- short undo_direction;
+ int undo_direction; /* eUndoStepDir */
/** Variables needed for reading from file. */
gzFile gzfiledes;
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index 767f24cf175..3b9ad64770d 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -339,7 +339,7 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo
NodeImageMultiFile *nimf = node->storage;
bNodeSocket *sock;
- /* CMP_NODE_OUTPUT_MULTI_FILE has been redeclared as CMP_NODE_OUTPUT_FILE */
+ /* CMP_NODE_OUTPUT_MULTI_FILE has been re-declared as CMP_NODE_OUTPUT_FILE */
node->type = CMP_NODE_OUTPUT_FILE;
/* initialize the node-wide image format from render data, if available */
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index df9268f0da1..d8ab8d6f32a 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1190,7 +1190,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
- /* Remove old deprecated region from filebrowsers */
+ /* Remove old deprecated region from file-browsers. */
else if (sl->spacetype == SPACE_FILE) {
LISTBASE_FOREACH (ARegion *, region, regionbase) {
if (region->regiontype == RGN_TYPE_CHANNELS) {
@@ -1657,7 +1657,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "falloff_angle")) {
for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
br->falloff_angle = DEG2RADF(80);
- /* These flags are used for new feautres. They are not related to falloff_angle */
+ /* These flags are used for new features. They are not related to `falloff_angle`. */
br->flag &= ~(BRUSH_INVERT_TO_SCRAPE_FILL | BRUSH_ORIGINAL_PLANE |
BRUSH_GRAB_ACTIVE_VERTEX | BRUSH_SCENE_SPACING | BRUSH_FRONTFACE_FALLOFF);
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 7dc2c9e86ee..0e90d9b6045 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -1390,7 +1390,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
}
}
- /* Cleanup deprecated flag from particlesettings data-blocks. */
+ /* Cleanup deprecated flag from particle-settings data-blocks. */
for (ParticleSettings *part = bmain->particles.first; part; part = part->id.next) {
part->draw &= ~PART_DRAW_EMITTER;
}
@@ -2110,7 +2110,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
for (Tex *tex = bmain->textures.first; tex; tex = tex->id.next) {
- /* Removed envmap, pointdensity, voxeldata, ocean textures. */
+ /* Removed environment map, point-density, voxel-data, ocean textures. */
if (ELEM(tex->type, 10, 14, 15, 16)) {
tex->type = 0;
}
@@ -4303,7 +4303,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- /* Elatic deform brush */
+ /* Elastic deform brush */
for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
if (br->ob_mode & OB_MODE_SCULPT && br->elastic_deform_volume_preservation == 0.0f) {
br->elastic_deform_volume_preservation = 0.5f;
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 60256359ea0..78d60715aa5 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -475,7 +475,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
bGPDframe *gpf = gpl->frames.first;
if (gpf && gpf->framenum > scene->r.sfra) {
- bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf);
+ bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf, true);
gpf_dup->framenum = scene->r.sfra;
BLI_addhead(&gpl->frames, gpf_dup);
}
@@ -499,7 +499,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
/**
* Make sure Emission Alpha fcurve and drivers is properly mapped after the Emission Strength
* got introduced.
- * */
+ */
/**
* Effectively we are replacing the (animation of) node socket input 18 with 19.
@@ -510,7 +510,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
*
* The for loop for the input ids is at the top level otherwise we lose the animation
* keyframe data.
- * */
+ */
for (int input_id = 21; input_id >= 18; input_id--) {
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
@@ -658,7 +658,7 @@ static void do_versions_291_fcurve_handles_limit(FCurve *fcu)
{
uint i = 1;
for (BezTriple *bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- /* Only adjust bezier keyframes. */
+ /* Only adjust bezier key-frames. */
if (bezt->ipo != BEZT_IPO_BEZ) {
continue;
}
@@ -735,6 +735,23 @@ static void version_node_socket_name(bNodeTree *ntree,
}
}
+static void version_node_join_geometry_for_multi_input_socket(bNodeTree *ntree)
+{
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
+ if (link->tonode->type == GEO_NODE_JOIN_GEOMETRY && !(link->tosock->flag & SOCK_MULTI_INPUT)) {
+ link->tosock = link->tonode->inputs.first;
+ }
+ }
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == GEO_NODE_JOIN_GEOMETRY) {
+ bNodeSocket *socket = node->inputs.first;
+ socket->flag |= SOCK_MULTI_INPUT;
+ socket->limit = 4095;
+ nodeRemoveSocket(ntree, node, socket->next);
+ }
+ }
+}
+
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
@@ -1097,10 +1114,10 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
if (!MAIN_VERSION_ATLEAST(bmain, 291, 5)) {
- /* Fix fcurves to allow for new bezier handles behaviour (T75881 and D8752). */
+ /* Fix fcurves to allow for new bezier handles behavior (T75881 and D8752). */
for (bAction *act = bmain->actions.first; act; act = act->id.next) {
for (FCurve *fcu = act->curves.first; fcu; fcu = fcu->next) {
- /* Only need to fix Bezier curves with at least 2 keyframes. */
+ /* Only need to fix Bezier curves with at least 2 key-frames. */
if (fcu->totvert < 2 || fcu->bezt == NULL) {
continue;
}
@@ -1548,7 +1565,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_END;
}
- if (!MAIN_VERSION_ATLEAST(bmain, 292, 13)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 293, 1)) {
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type == NTREE_GEOMETRY) {
version_node_socket_name(ntree, GEO_NODE_BOOLEAN, "Geometry A", "Geometry 1");
@@ -1573,7 +1590,8 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- if (!MAIN_VERSION_ATLEAST(bmain, 292, 14)) {
+ 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;
@@ -1590,28 +1608,112 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_END;
}
- /**
- * 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, 293, 1)) {
+ /* Grease pencil layer transform matrix. */
+ if (!DNA_struct_elem_find(fd->filesdna, "bGPDlayer", "float", "location[0]")) {
+ LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ zero_v3(gpl->location);
+ zero_v3(gpl->rotation);
+ copy_v3_fl(gpl->scale, 1.0f);
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+ }
+ }
+ }
+ /* Fix Fill factor for grease pencil fill brushes. */
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
+ if ((brush->gpencil_settings) && (brush->gpencil_settings->fill_factor == 0.0f)) {
+ brush->gpencil_settings->fill_factor = 1.0f;
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 293, 3)) {
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type != NTREE_GEOMETRY) {
+ continue;
+ }
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == GEO_NODE_POINT_INSTANCE && node->storage == NULL) {
+ NodeGeometryPointInstance *data = (NodeGeometryPointInstance *)MEM_callocN(
+ sizeof(NodeGeometryPointInstance), __func__);
+ data->instance_type = node->custom1;
+ data->flag = (node->custom2 ? 0 : GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION);
+ node->storage = data;
+ }
+ }
+ }
+ FOREACH_NODETREE_END;
+ }
- /* UV/Image Max resolution images in image editor. */
+ if (!MAIN_VERSION_ATLEAST(bmain, 293, 4)) {
+ /* Add support for all operations to the "Attribute Math" node. */
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == GEO_NODE_ATTRIBUTE_MATH) {
+ NodeAttributeMath *data = (NodeAttributeMath *)node->storage;
+ data->input_type_c = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
+ }
+ }
+ }
+ }
+ FOREACH_NODETREE_END;
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 293, 5)) {
+ /* Change Nishita sky model Altitude unit. */
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type == NTREE_SHADER) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == SH_NODE_TEX_SKY && node->storage) {
+ NodeTexSky *tex = (NodeTexSky *)node->storage;
+ tex->altitude *= 1000.0f;
+ }
+ }
+ }
+ }
+ FOREACH_NODETREE_END;
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 293, 6)) {
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
+ /* UV/Image Max resolution images in image editor. */
if (space->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)space;
sima->iuser.flag |= IMA_SHOW_MAX_RESOLUTION;
}
+ /* Enable Outliner render visibility column. */
+ else if (space->spacetype == SPACE_OUTLINER) {
+ SpaceOutliner *space_outliner = (SpaceOutliner *)space;
+ space_outliner->show_restrict_flags |= SO_RESTRICT_RENDER;
+ }
}
}
}
}
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 293, 7)) {
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ version_node_join_geometry_for_multi_input_socket(ntree);
+ }
+ }
+ FOREACH_NODETREE_END;
+ }
+ /**
+ * 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_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c
index 631abe10ddc..816b90491aa 100644
--- a/source/blender/blenloader/intern/versioning_cycles.c
+++ b/source/blender/blenloader/intern/versioning_cycles.c
@@ -1420,7 +1420,7 @@ void do_versions_after_linking_cycles(Main *bmain)
}
if (!MAIN_VERSION_ATLEAST(bmain, 280, 64)) {
- /* Unfiy Cycles and Eevee settings. */
+ /* Unify Cycles and Eevee settings. */
Scene *scene = bmain->scenes.first;
const char *engine = (scene) ? scene->r.engine : "CYCLES";
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index 322830282e9..3d39181cd32 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -273,6 +273,15 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
{
/* Keep this block, even when empty. */
FROM_DEFAULT_V4_UCHAR(space_properties.active);
+
+ FROM_DEFAULT_V4_UCHAR(space_info.info_error);
+ FROM_DEFAULT_V4_UCHAR(space_info.info_warning);
+ FROM_DEFAULT_V4_UCHAR(space_info.info_info);
+ FROM_DEFAULT_V4_UCHAR(space_info.info_debug);
+ FROM_DEFAULT_V4_UCHAR(space_info.info_debug_text);
+ FROM_DEFAULT_V4_UCHAR(space_info.info_property);
+ FROM_DEFAULT_V4_UCHAR(space_info.info_error);
+ FROM_DEFAULT_V4_UCHAR(space_info.info_operator);
}
#undef FROM_DEFAULT_V4_UCHAR
@@ -827,6 +836,13 @@ void blo_do_versions_userdef(UserDef *userdef)
}
}
+ if (!USER_VERSION_ATLEAST(293, 2)) {
+ /* Enable asset browser features by default for alpha testing.
+ * BLO_sanitize_experimental_features_userpref_blend() will disable it again for non-alpha
+ * builds. */
+ userdef->experimental.use_asset_browser = true;
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
@@ -838,6 +854,9 @@ void blo_do_versions_userdef(UserDef *userdef)
*/
{
/* Keep this block, even when empty. */
+ if (userdef->gizmo_size_navigate_v3d == 0) {
+ userdef->gizmo_size_navigate_v3d = 80;
+ }
}
LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) {
diff --git a/source/blender/blentranslation/intern/blt_lang.c b/source/blender/blentranslation/intern/blt_lang.c
index bd0352d3e80..97a1a83792a 100644
--- a/source/blender/blentranslation/intern/blt_lang.c
+++ b/source/blender/blentranslation/intern/blt_lang.c
@@ -48,10 +48,6 @@
#include "MEM_guardedalloc.h"
-/* Cached IME support flags */
-static bool ime_is_lang_supported = false;
-static void blt_lang_check_ime_supported(void);
-
#ifdef WITH_INTERNATIONAL
# include "BLI_fileops.h"
@@ -205,7 +201,7 @@ void BLT_lang_init(void)
const char *const messagepath = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale");
#endif
- /* Make sure LANG is correct and wouldn't cause #std::rumtime_error. */
+ /* Make sure LANG is correct and wouldn't cause #std::runtime_error. */
#ifndef _WIN32
/* TODO(sergey): This code only ensures LANG is set properly, so later when
* Cycles will try to use file system API from boost there will be no runtime
@@ -286,7 +282,6 @@ void BLT_lang_set(const char *str)
#else
(void)str;
#endif
- blt_lang_check_ime_supported();
IMB_thumb_clear_translations();
}
@@ -380,24 +375,13 @@ void BLT_lang_locale_explode(const char *locale,
}
}
-/**
- * Test if the translation context allows IME input - used to
- * avoid weird character drawing if IME inputs non-ascii chars.
- */
-static void blt_lang_check_ime_supported(void)
-{
-#ifdef WITH_INPUT_IME
- const char *uilng = BLT_lang_get();
- ime_is_lang_supported = STR_ELEM(uilng, "zh_CN", "zh_TW", "ja_JP");
-#else
- ime_is_lang_supported = false;
-#endif
-}
-
+/* Note that "lang" here is the _output_ display language. We used to restrict
+ * IME for keyboard _input_ language because our multilingual font was only used
+ * when some output languages were selected. That font is used all the time now. */
bool BLT_lang_is_ime_supported(void)
{
#ifdef WITH_INPUT_IME
- return ime_is_lang_supported;
+ return true;
#else
return false;
#endif
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 9899d67c008..65f3d8bbad3 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -238,7 +238,6 @@ typedef struct BMesh {
uint use_toolflags : 1;
int toolflag_index;
- struct BMOperator *currentop;
CustomData vdata, edata, ldata, pdata;
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index b913bdd12e4..cf907862120 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -2158,7 +2158,7 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
l_f1->next->prev = l_f2->prev;
l_f2->prev->next = l_f1->next;
- /* if l_f1 was baseloop, make l_f1->next the base. */
+ /* If `l_f1` was base-loop, make `l_f1->next` the base. */
if (BM_FACE_FIRST_LOOP(f1) == l_f1) {
BM_FACE_FIRST_LOOP(f1) = l_f1->next;
}
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c
index ec97ea51047..51a6ada6c42 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.c
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.c
@@ -450,7 +450,7 @@ void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops, const boo
}
mul_v3_fl(cent, 1.0f / (float)tot);
- /* find far outest loop */
+ /* Find the furthest out loop. */
{
BMEdgeLoopStore *el_store_best = NULL;
float len_best_sq = -1.0f;
diff --git a/source/blender/bmesh/intern/bmesh_error.h b/source/blender/bmesh/intern/bmesh_error.h
index 1837ad8dd71..41d02e334fb 100644
--- a/source/blender/bmesh/intern/bmesh_error.h
+++ b/source/blender/bmesh/intern/bmesh_error.h
@@ -25,7 +25,7 @@
/*----------- bmop error system ----------*/
/* pushes an error onto the bmesh error stack.
- * if msg is null, then the default message for the errorcode is used.*/
+ * if msg is null, then the default message for the `errcode` is used. */
void BMO_error_raise(BMesh *bm, BMOperator *owner, int errcode, const char *msg);
/* gets the topmost error from the stack.
@@ -33,7 +33,7 @@ void BMO_error_raise(BMesh *bm, BMOperator *owner, int errcode, const char *msg)
int BMO_error_get(BMesh *bm, const char **msg, BMOperator **op);
bool BMO_error_occurred(BMesh *bm);
-/* same as geterror, only pops the error off the stack as well */
+/* Same as #BMO_error_get, only pops the error off the stack as well. */
int BMO_error_pop(BMesh *bm, const char **msg, BMOperator **op);
void BMO_error_clear(BMesh *bm);
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index a15408d43be..6857a1f3929 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -342,8 +342,12 @@ static void mdisp_axis_from_quad(const float v1[3],
normalize_v3(r_axis_y);
}
-/* tl is loop to project onto, l is loop whose internal displacement, co, is being
- * projected. x and y are location in loop's mdisps grid of point co. */
+/**
+ * \param l_src: is loop whose internal displacement.
+ * \param l_dst: is loop to project onto.
+ * \param p: The point being projected.
+ * \param r_axis_x, r_axis_y: The location in loop's #CD_MDISPS grid of point `p`.
+ */
static bool mdisp_in_mdispquad(BMLoop *l_src,
BMLoop *l_dst,
const float l_dst_f_center[3],
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 44e3ef6e6ee..c81d4f9b67c 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -177,7 +177,7 @@ void *BM_iter_as_arrayN(BMesh *bm,
BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
- /* we can't rely on coun't being set */
+ /* We can't rely on #BMIter.count being set. */
switch (itype) {
case BM_VERTS_OF_MESH:
iter.count = bm->totvert;
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 4c72b802396..8e5ed9c3bf0 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -802,7 +802,7 @@ void BM_edge_calc_rotate(BMEdge *e, const bool ccw, BMLoop **r_l1, BMLoop **r_l2
/* we know this will work */
BM_edge_face_pair(e, &fa, &fb);
- /* so we can use ccw variable correctly,
+ /* so we can use `ccw` variable correctly,
* otherwise we could use the edges verts direct */
BM_edge_ordered_verts(e, &v1, &v2);
@@ -886,7 +886,7 @@ bool BM_edge_rotate_check_degenerate(BMEdge *e, BMLoop *l1, BMLoop *l2)
/* verts from the loops passed */
BMVert *v1, *v2;
- /* these are the opposite verts - the verts that _would_ be used if 'ccw' was inverted*/
+ /* These are the opposite verts - the verts that _would_ be used if `ccw` was inverted. */
BMVert *v1_alt, *v2_alt;
/* this should have already run */
@@ -1070,7 +1070,7 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f
BM_face_normal_flip(bm, fb);
if (ccw) {
- /* needed otherwise ccw toggles direction */
+ /* Needed otherwise `ccw` toggles direction */
e_new->l = e_new->l->radial_next;
}
}
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index d8cdff1a4cc..bccac006e8e 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -54,7 +54,8 @@
#include "DNA_modifier_types.h"
-/* The formatting of these bmesh operators is parsed by
+/**
+ * The formatting of these bmesh operators is parsed by
* 'doc/python_api/rst_from_bmesh_opdefines.py'
* for use in python docs, so reStructuredText may be used
* rather than doxygen syntax.
@@ -65,8 +66,7 @@
* """
* Region Extend.
*
- * paragraph1, Extends bleh bleh bleh.
- * Bleh Bleh bleh.
+ * paragraph1, Extends on the title above.
*
* Another paragraph.
*
@@ -731,7 +731,7 @@ static BMOpDefine bmo_edgenet_fill_def = {
*
* - One single loop; an edge is added to connect the ends
* - Two loops; two edges are added to connect the endpoints (based on the
- * shortest distance between each endpont).
+ * shortest distance between each endpoint).
*/
static BMOpDefine bmo_edgenet_prepare_def = {
"edgenet_prepare",
@@ -1268,7 +1268,7 @@ static BMOpDefine bmo_subdivide_edges_def = {
{"quad_corner_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edges_quad_corner_type}, /* quad corner type */
{"use_grid_fill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */
{"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
- {"use_only_quads", BMO_OP_SLOT_BOOL}, /* only subdivide quads (for loopcut) */
+ {"use_only_quads", BMO_OP_SLOT_BOOL}, /* Only subdivide quads (for loop-cut). */
{"use_sphere", BMO_OP_SLOT_BOOL}, /* for making new primitives only */
{"use_smooth_even", BMO_OP_SLOT_BOOL}, /* maintain even offset when smoothing */
{{'\0'}},
@@ -1394,7 +1394,7 @@ static BMOpDefine bmo_duplicate_def = {
/* slots_out */
{{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- /* facemap maps from source faces to dupe
+ /* face_map maps from source faces to dupe
* faces, and from dupe faces to source faces */
{"vert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
{"edge_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 2f7d91c78c4..2d9e244e54d 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -24,7 +24,7 @@
/*--------defines/enumerations for specific operators-------*/
-/*quad innervert values*/
+/* Quad `innervert` values. */
enum {
SUBD_CORNER_INNERVERT,
SUBD_CORNER_PATH,
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 1d000b3b232..dcf9717465c 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -1566,7 +1566,7 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm,
for (uint g_index = 1; g_index < group_arr_len; g_index++) {
struct EdgeGroupIsland *g = group_arr[g_index];
- /* the range of verts this group uses in 'verts_arr' (not uncluding the last index) */
+ /* The range of verts this group uses in 'verts_arr' (not including the last index). */
vert_range[0] = vert_range[1];
vert_range[1] += g->vert_len;
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index ef4a9c9de1c..cfdce0b749b 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -143,7 +143,7 @@ void bmesh_disk_vert_replace(BMEdge *e, BMVert *v_dst, BMVert *v_src)
*
* The loop cycle keeps track of a faces vertices and edges. It should be noted that the
* direction of a loop cycle is either CW or CCW depending on the face normal, and is
- * not oriented to the faces editedges.
+ * not oriented to the faces edit-edges.
*
* Functions relating to this cycle:
* - bmesh_cycle_XXX family of functions.
@@ -537,7 +537,7 @@ int bmesh_radial_length(const BMLoop *l)
do {
if (UNLIKELY(!l_iter)) {
- /* radial cycle is broken (not a circulat loop) */
+ /* Radial cycle is broken (not a circular loop). */
BMESH_ASSERT(0);
return 0;
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers.h b/source/blender/bmesh/intern/bmesh_walkers.h
index a973e12a4c7..22ee8809a19 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.h
+++ b/source/blender/bmesh/intern/bmesh_walkers.h
@@ -122,7 +122,7 @@ enum {
BMW_CONNECTED_VERTEX,
/* end of array index enum vals */
- /* do not intitialze function pointers and struct size in BMW_init */
+ /* Do not initialize function pointers and struct size in #BMW_init. */
BMW_CUSTOM,
BMW_MAXWALKERS,
};
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index c23551ecca7..647a22baaeb 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -29,7 +29,7 @@
#include "bmesh.h"
#include "intern/bmesh_walkers_private.h"
-/* pop into stack memory (common operation) */
+/* Pop into stack memory (common operation). */
#define BMW_state_remove_r(walker, owalk) \
{ \
memcpy(owalk, BMW_current_state(walker), sizeof(*(owalk))); \
@@ -86,7 +86,7 @@ static bool bmw_mask_check_face(BMWalker *walker, BMFace *f)
static bool bmw_edge_is_wire(const BMWalker *walker, const BMEdge *e)
{
if (walker->flag & BMW_FLAG_TEST_HIDDEN) {
- /* check if this is a wire edge, ignoring hidden faces */
+ /* Check if this is a wire edge, ignoring hidden faces. */
if (BM_edge_is_wire(e)) {
return true;
}
@@ -137,8 +137,7 @@ static void bmw_VertShellWalker_begin(BMWalker *walker, void *data)
switch (h->htype) {
case BM_VERT: {
- /* starting the walk at a vert, add all the edges
- * to the worklist */
+ /* Starting the walk at a vert, add all the edges to the work-list. */
v = (BMVert *)h;
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
bmw_VertShellWalker_visitEdge(walker, e);
@@ -147,8 +146,7 @@ static void bmw_VertShellWalker_begin(BMWalker *walker, void *data)
}
case BM_EDGE: {
- /* starting the walk at an edge, add the single edge
- * to the worklist */
+ /* Starting the walk at an edge, add the single edge to the work-list. */
e = (BMEdge *)h;
bmw_VertShellWalker_visitEdge(walker, e);
break;
@@ -201,7 +199,7 @@ static void *bmw_VertShellWalker_step(BMWalker *walker)
BMW_state_remove(walker);
- /* find the next edge whose other vertex has not been visite */
+ /* Find the next edge whose other vertex has not been visited. */
curedge = shellWalk.curedge;
do {
if (!BLI_gset_haskey(walker->visit_set, curedge)) {
@@ -212,11 +210,11 @@ static void *bmw_VertShellWalker_step(BMWalker *walker)
v_old = BM_edge_other_vert(curedge, shellWalk.base);
- /* push a new state onto the stac */
+ /* Push a new state onto the stack. */
newState = BMW_state_add(walker);
BLI_gset_insert(walker->visit_set, curedge);
- /* populate the new stat */
+ /* Populate the new state. */
newState->base = v_old;
newState->curedge = curedge;
@@ -266,8 +264,7 @@ static void bmw_LoopShellWalker_begin(BMWalker *walker, void *data)
switch (h->htype) {
case BM_LOOP: {
- /* starting the walk at a vert, add all the edges
- * to the worklist */
+ /* Starting the walk at a vert, add all the edges to the work-list. */
BMLoop *l = (BMLoop *)h;
bmw_LoopShellWalker_visitLoop(walker, l);
break;
@@ -292,7 +289,7 @@ static void bmw_LoopShellWalker_begin(BMWalker *walker, void *data)
case BM_FACE: {
BMFace *f = (BMFace *)h;
BMLoop *l = BM_FACE_FIRST_LOOP(f);
- /* walker will handle other loops within the face */
+ /* Walker will handle other loops within the face. */
bmw_LoopShellWalker_visitLoop(walker, l);
break;
}
@@ -312,7 +309,7 @@ static void bmw_LoopShellWalker_step_impl(BMWalker *walker, BMLoop *l)
BMEdge *e_edj_pair[2];
int i;
- /* seems paranoid, but one caller also walks edges */
+ /* Seems paranoid, but one caller also walks edges. */
BLI_assert(l->head.htype == BM_LOOP);
bmw_LoopShellWalker_visitLoop(walker, l->next);
@@ -409,7 +406,7 @@ static void bmw_LoopShellWireWalker_visitVert(BMWalker *walker, BMVert *v, const
bmw_LoopShellWalker_visitEdgeWire(walker, e);
- /* check if we step onto a non-wire vertex */
+ /* Check if we step onto a non-wire vertex. */
v_other = BM_edge_other_vert(e, v);
BM_ITER_ELEM (l, &iter, v_other, BM_LOOPS_OF_VERT) {
@@ -463,7 +460,7 @@ static void bmw_LoopShellWireWalker_begin(BMWalker *walker, void *data)
break;
}
case BM_FACE: {
- /* wire verts will be walked over */
+ /* Wire verts will be walked over. */
break;
}
default:
@@ -581,12 +578,12 @@ static void bmw_ConnectedVertexWalker_visitVertex(BMWalker *walker, BMVert *v)
BMwConnectedVertexWalker *vwalk;
if (BLI_gset_haskey(walker->visit_set, v)) {
- /* already visited */
+ /* Already visited. */
return;
}
if (!bmw_mask_check_vert(walker, v)) {
- /* not flagged for walk */
+ /* Not flagged for walk. */
return;
}
@@ -670,10 +667,9 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
BMEdge *e;
BMFace *f;
BMLoop *l;
- /* int found = 0; */
memcpy(&owalk, BMW_current_state(walker), sizeof(owalk));
- /* normally we'd remove here, but delay until after error checking */
+ /* Normally we'd remove here, but delay until after error checking. */
iwalk = &owalk;
l = iwalk->curloop;
@@ -681,7 +677,7 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
v = BM_edge_other_vert(e, iwalk->lastv);
- /* pop off current state */
+ /* Pop off current state. */
BMW_state_remove(walker);
f = l->f;
@@ -699,7 +695,7 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
}
}
else {
- /* treat non-manifold edges as boundaries */
+ /* Treat non-manifold edges as boundaries. */
f = l->f;
e = l->e;
break;
@@ -717,9 +713,16 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
iwalk = BMW_state_add(walker);
iwalk->base = owalk.base;
- // if (!BMO_face_flag_test(walker->bm, l->f, walker->restrictflag))
- // iwalk->curloop = l->radial_next;
- iwalk->curloop = l; // else iwalk->curloop = l;
+#if 0
+ if (!BMO_face_flag_test(walker->bm, l->f, walker->restrictflag)) {
+ iwalk->curloop = l->radial_next;
+ }
+ else {
+ iwalk->curloop = l;
+ }
+#else
+ iwalk->curloop = l;
+#endif
iwalk->lastv = v;
return owalk.curloop;
@@ -763,7 +766,7 @@ static void *bmw_IslandWalker_step_ex(BMWalker *walker, bool only_manifold)
l_iter = l_first = BM_FACE_FIRST_LOOP(iwalk->cur);
do {
- /* could skip loop here too, but don't add unless we need it */
+ /* Could skip loop here too, but don't add unless we need it. */
if (!bmw_mask_check_edge(walker, l_iter->e)) {
continue;
}
@@ -772,7 +775,7 @@ static void *bmw_IslandWalker_step_ex(BMWalker *walker, bool only_manifold)
if (only_manifold && (l_iter->radial_next != l_iter)) {
int face_count = 1;
- /* check other faces (not this one), ensure only one other can be walked onto. */
+ /* Check other faces (not this one), ensure only one other Can be walked onto. */
l_radial_iter = l_iter->radial_next;
do {
if (bmw_mask_check_face(walker, l_radial_iter->f)) {
@@ -796,7 +799,7 @@ static void *bmw_IslandWalker_step_ex(BMWalker *walker, bool only_manifold)
continue;
}
- /* saves checking BLI_gset_haskey below (manifold edges there's a 50% chance) */
+ /* Saves checking #BLI_gset_haskey below (manifold edges there's a 50% chance). */
if (f == iwalk->cur) {
continue;
}
@@ -947,12 +950,12 @@ static void bmw_EdgeLoopWalker_begin(BMWalker *walker, void *data)
}
if (f_best) {
- /* only use hub selection for 5+ sides else this could
+ /* Only use hub selection for 5+ sides else this could
* conflict with normal edge loop selection. */
lwalk->f_hub = f_best->len > 4 ? f_best : NULL;
}
else {
- /* edge doesn't have any faces connected to it */
+ /* Edge doesn't have any faces connected to it. */
lwalk->f_hub = NULL;
}
}
@@ -960,7 +963,7 @@ static void bmw_EdgeLoopWalker_begin(BMWalker *walker, void *data)
lwalk->f_hub = NULL;
}
- /* rewind */
+ /* Rewind. */
while ((owalk_pt = BMW_current_state(walker))) {
owalk = *((BMwEdgeLoopWalker *)owalk_pt);
BMW_walk(walker);
@@ -1007,7 +1010,7 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker)
nexte = BM_edge_exists(v, l->v);
if (bmw_mask_check_edge(walker, nexte) && !BLI_gset_haskey(walker->visit_set, nexte) &&
- /* never step onto a boundary edge, this gives odd-results */
+ /* Never step onto a boundary edge, this gives odd-results. */
(BM_edge_is_boundary(nexte) == false)) {
lwalk = BMW_state_add(walker);
lwalk->cur = nexte;
@@ -1024,7 +1027,7 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker)
else if (l == NULL) { /* WIRE EDGE */
BMIter eiter;
- /* match trunk: mark all connected wire edges */
+ /* Match trunk: mark all connected wire edges. */
for (int i = 0; i < 2; i++) {
v = i ? e->v2 : e->v1;
@@ -1051,9 +1054,8 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker)
vert_edge_tot = BM_vert_edge_count_nonwire(v);
- /* Typical loopiong over edges in the middle of a mesh */
- /* However, why use 2 here at all?
- * I guess for internal ngon loops it can be useful. Antony R. */
+ /* Typical looping over edges in the middle of a mesh.
+ * Why use 2 here at all? - for internal ngon loops it can be useful. */
if (ELEM(vert_edge_tot, 4, 2)) {
int i_opposite = vert_edge_tot / 2;
int i = 0;
@@ -1094,15 +1096,15 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker)
vert_edge_tot = BM_vert_edge_count_nonwire(v);
- /* check if we should step, this is fairly involved */
+ /* Check if we should step, this is fairly involved. */
if (
- /* walk over boundary of faces but stop at corners */
+ /* Walk over boundary of faces but stop at corners. */
(owalk.is_single == false && vert_edge_tot > 2) ||
- /* initial edge was a boundary, so is this edge and vertex is only a part of this face
- * this lets us walk over the boundary of an ngon which is handy */
+ /* Initial edge was a boundary, so is this edge and vertex is only a part of this face
+ * this lets us walk over the boundary of an ngon which is handy. */
(owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e))) {
- /* find next boundary edge in the fan */
+ /* Find next boundary edge in the fan. */
do {
l = BM_loop_other_edge_loop(l, v);
if (BM_edge_is_manifold(l->e)) {
@@ -1148,14 +1150,16 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker)
*
* Starts at a tool-flagged face and walks over the face loop
* Conditions for starting and stepping the face loop have been
- * tuned in an attempt to match the face loops built by EditMesh
+ * tuned in an attempt to match the face loops built by edit-mesh
* \{ */
-/* Check whether the face loop should includes the face specified
- * by the given BMLoop */
+/**
+ * Check whether the face loop should includes the face specified
+ * by the given #BMLoop.
+ */
static bool bmw_FaceLoopWalker_include_face(BMWalker *walker, BMLoop *l)
{
- /* face must have degree 4 */
+ /* Face must have degree 4. */
if (l->f->len != 4) {
return false;
}
@@ -1164,7 +1168,7 @@ static bool bmw_FaceLoopWalker_include_face(BMWalker *walker, BMLoop *l)
return false;
}
- /* the face must not have been already visited */
+ /* The face must not have been already visited. */
if (BLI_gset_haskey(walker->visit_set, l->f) && BLI_gset_haskey(walker->visit_set_alt, l->e)) {
return false;
}
@@ -1172,23 +1176,22 @@ static bool bmw_FaceLoopWalker_include_face(BMWalker *walker, BMLoop *l)
return true;
}
-/* Check whether the face loop can start from the given edge */
+/* Check whether the face loop can start from the given edge. */
static bool bmw_FaceLoopWalker_edge_begins_loop(BMWalker *walker, BMEdge *e)
{
- /* There is no face loop starting from a wire edge */
+ /* There is no face loop starting from a wire edge. */
if (BM_edge_is_wire(e)) {
return false;
}
- /* Don't start a loop from a boundary edge if it cannot
- * be extended to cover any faces */
+ /* Don't start a loop from a boundary edge if it cannot be extended to cover any faces. */
if (BM_edge_is_boundary(e)) {
if (!bmw_FaceLoopWalker_include_face(walker, e->l)) {
return false;
}
}
- /* Don't start a face loop from non-manifold edges */
+ /* Don't start a face loop from non-manifold edges. */
if (!BM_edge_is_manifold(e)) {
return false;
}
@@ -1212,7 +1215,7 @@ static void bmw_FaceLoopWalker_begin(BMWalker *walker, void *data)
lwalk->no_calc = false;
BLI_gset_insert(walker->visit_set, lwalk->l->f);
- /* rewind */
+ /* Rewind. */
while ((owalk_pt = BMW_current_state(walker))) {
owalk = *((BMwFaceLoopWalker *)owalk_pt);
BMW_walk(walker);
@@ -1277,7 +1280,7 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker)
lwalk->no_calc = false;
}
- /* both may already exist */
+ /* Both may already exist. */
BLI_gset_add(walker->visit_set_alt, l->e);
BLI_gset_add(walker->visit_set, l->f);
}
@@ -1312,7 +1315,7 @@ static void bmw_EdgeringWalker_begin(BMWalker *walker, void *data)
BLI_gset_insert(walker->visit_set, lwalk->l->e);
- /* rewind */
+ /* Rewind. */
while ((owalk_pt = BMW_current_state(walker))) {
owalk = *((BMwEdgeringWalker *)owalk_pt);
BMW_walk(walker);
@@ -1370,10 +1373,10 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
e = l->e;
if (!EDGE_CHECK(e)) {
- /* walker won't traverse to a non-manifold edge, but may
+ /* Walker won't traverse to a non-manifold edge, but may
* be started on one, and should not traverse *away* from
* a non-manifold edge (non-manifold edges are never in an
- * edge ring with manifold edges */
+ * edge ring with manifold edges. */
return e;
}
@@ -1394,7 +1397,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
i -= 2;
}
}
- /* only walk to manifold edge */
+ /* Only walk to manifold edge. */
if ((l->f->len % 2 == 0) && EDGE_CHECK(l->e) && !BLI_gset_haskey(walker->visit_set, l->e))
#else
@@ -1404,7 +1407,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
if ((l->f->len != 4) || !EDGE_CHECK(l->e) || !bmw_mask_check_face(walker, l->f)) {
l = owalk.l->next->next;
}
- /* only walk to manifold edge */
+ /* Only walk to manifold edge. */
if ((l->f->len == 4) && EDGE_CHECK(l->e) && !BLI_gset_haskey(walker->visit_set, l->e))
#endif
{
@@ -1547,8 +1550,8 @@ static void *bmw_UVEdgeWalker_step(BMWalker *walker)
return l;
}
- /* go over loops around l->v and nl->v and see which ones share l and nl's
- * mloopuv's coordinates. in addition, push on l->next if necessary */
+ /* Go over loops around `l->v` and `l->next->v` and see which ones share `l` and `l->next`
+ * UV's coordinates. in addition, push on `l->next` if necessary. */
for (i = 0; i < 2; i++) {
BMIter liter;
BMLoop *l_pivot, *l_radial;
@@ -1600,7 +1603,7 @@ static BMWalker bmw_VertShellWalker_Type = {
bmw_VertShellWalker_yield,
sizeof(BMwShellWalker),
BMW_BREADTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_EDGE, /* Valid restrict masks. */
};
static BMWalker bmw_LoopShellWalker_Type = {
@@ -1610,7 +1613,7 @@ static BMWalker bmw_LoopShellWalker_Type = {
bmw_LoopShellWalker_yield,
sizeof(BMwLoopShellWalker),
BMW_BREADTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_EDGE, /* Valid restrict masks. */
};
static BMWalker bmw_LoopShellWireWalker_Type = {
@@ -1620,7 +1623,7 @@ static BMWalker bmw_LoopShellWireWalker_Type = {
bmw_LoopShellWireWalker_yield,
sizeof(BMwLoopShellWireWalker),
BMW_BREADTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_EDGE, /* Valid restrict masks. */
};
static BMWalker bmw_FaceShellWalker_Type = {
@@ -1630,7 +1633,7 @@ static BMWalker bmw_FaceShellWalker_Type = {
bmw_FaceShellWalker_yield,
sizeof(BMwShellWalker),
BMW_BREADTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_EDGE, /* Valid restrict masks. */
};
static BMWalker bmw_IslandboundWalker_Type = {
@@ -1640,7 +1643,7 @@ static BMWalker bmw_IslandboundWalker_Type = {
bmw_IslandboundWalker_yield,
sizeof(BMwIslandboundWalker),
BMW_DEPTH_FIRST,
- BM_FACE, /* valid restrict masks */
+ BM_FACE, /* Valid restrict masks. */
};
static BMWalker bmw_IslandWalker_Type = {
@@ -1650,17 +1653,17 @@ static BMWalker bmw_IslandWalker_Type = {
bmw_IslandWalker_yield,
sizeof(BMwIslandWalker),
BMW_BREADTH_FIRST,
- BM_EDGE | BM_FACE, /* valid restrict masks */
+ BM_EDGE | BM_FACE, /* Valid restrict masks. */
};
static BMWalker bmw_IslandManifoldWalker_Type = {
BM_FACE,
bmw_IslandWalker_begin,
- bmw_IslandManifoldWalker_step, /* only difference with BMW_ISLAND */
+ bmw_IslandManifoldWalker_step, /* Only difference with #BMW_ISLAND. */
bmw_IslandWalker_yield,
sizeof(BMwIslandWalker),
BMW_BREADTH_FIRST,
- BM_EDGE | BM_FACE, /* valid restrict masks */
+ BM_EDGE | BM_FACE, /* Valid restrict masks. */
};
static BMWalker bmw_EdgeLoopWalker_Type = {
@@ -1671,7 +1674,7 @@ static BMWalker bmw_EdgeLoopWalker_Type = {
sizeof(BMwEdgeLoopWalker),
BMW_DEPTH_FIRST,
0,
- /* valid restrict masks */ /* could add flags here but so far none are used */
+ /* Valid restrict masks. */ /* Could add flags here but so far none are used. */
};
static BMWalker bmw_FaceLoopWalker_Type = {
@@ -1682,7 +1685,7 @@ static BMWalker bmw_FaceLoopWalker_Type = {
sizeof(BMwFaceLoopWalker),
BMW_DEPTH_FIRST,
0,
- /* valid restrict masks */ /* could add flags here but so far none are used */
+ /* Valid restrict masks. */ /* Could add flags here but so far none are used. */
};
static BMWalker bmw_EdgeringWalker_Type = {
@@ -1692,7 +1695,7 @@ static BMWalker bmw_EdgeringWalker_Type = {
bmw_EdgeringWalker_yield,
sizeof(BMwEdgeringWalker),
BMW_DEPTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_EDGE, /* Valid restrict masks. */
};
static BMWalker bmw_EdgeboundaryWalker_Type = {
@@ -1712,7 +1715,7 @@ static BMWalker bmw_UVEdgeWalker_Type = {
bmw_UVEdgeWalker_yield,
sizeof(BMwUVEdgeWalker),
BMW_DEPTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_EDGE, /* Valid restrict masks. */
};
static BMWalker bmw_ConnectedVertexWalker_Type = {
@@ -1722,23 +1725,23 @@ static BMWalker bmw_ConnectedVertexWalker_Type = {
bmw_ConnectedVertexWalker_yield,
sizeof(BMwConnectedVertexWalker),
BMW_BREADTH_FIRST,
- BM_VERT, /* valid restrict masks */
+ BM_VERT, /* Valid restrict masks. */
};
BMWalker *bm_walker_types[] = {
- &bmw_VertShellWalker_Type, /* BMW_VERT_SHELL */
- &bmw_LoopShellWalker_Type, /* BMW_LOOP_SHELL */
- &bmw_LoopShellWireWalker_Type, /* BMW_LOOP_SHELL_WIRE */
- &bmw_FaceShellWalker_Type, /* BMW_FACE_SHELL */
- &bmw_EdgeLoopWalker_Type, /* BMW_EDGELOOP */
- &bmw_FaceLoopWalker_Type, /* BMW_FACELOOP */
- &bmw_EdgeringWalker_Type, /* BMW_EDGERING */
- &bmw_EdgeboundaryWalker_Type, /* BMW_EDGEBOUNDARY */
- &bmw_UVEdgeWalker_Type, /* BMW_LOOPDATA_ISLAND */
- &bmw_IslandboundWalker_Type, /* BMW_ISLANDBOUND */
- &bmw_IslandWalker_Type, /* BMW_ISLAND */
- &bmw_IslandManifoldWalker_Type, /* BMW_ISLAND_MANIFOLD */
- &bmw_ConnectedVertexWalker_Type, /* BMW_CONNECTED_VERTEX */
+ &bmw_VertShellWalker_Type, /* #BMW_VERT_SHELL */
+ &bmw_LoopShellWalker_Type, /* #BMW_LOOP_SHELL */
+ &bmw_LoopShellWireWalker_Type, /* #BMW_LOOP_SHELL_WIRE */
+ &bmw_FaceShellWalker_Type, /* #BMW_FACE_SHELL */
+ &bmw_EdgeLoopWalker_Type, /* #BMW_EDGELOOP */
+ &bmw_FaceLoopWalker_Type, /* #BMW_FACELOOP */
+ &bmw_EdgeringWalker_Type, /* #BMW_EDGERING */
+ &bmw_EdgeboundaryWalker_Type, /* #BMW_EDGEBOUNDARY */
+ &bmw_UVEdgeWalker_Type, /* #BMW_LOOPDATA_ISLAND */
+ &bmw_IslandboundWalker_Type, /* #BMW_ISLANDBOUND */
+ &bmw_IslandWalker_Type, /* #BMW_ISLAND */
+ &bmw_IslandManifoldWalker_Type, /* #BMW_ISLAND_MANIFOLD */
+ &bmw_ConnectedVertexWalker_Type, /* #BMW_CONNECTED_VERTEX */
};
const int bm_totwalkers = ARRAY_SIZE(bm_walker_types);
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 8c2e820df63..da2603ad8cd 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -55,7 +55,7 @@ static bool UNUSED_FUNCTION(check_hole_in_region)(BMesh *bm, BMFace *f)
BMLoop *l2, *l3;
BMFace *f2;
- /* checks if there are any unmarked boundary edges in the face regio */
+ /* Checks if there are any unmarked boundary edges in the face region. */
BMW_init(&regwalker,
bm,
@@ -159,7 +159,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
}
BLI_array_clear(faces);
- faces = NULL; /* forces different allocatio */
+ faces = NULL; /* Forces different allocation. */
BMW_init(&regwalker,
bm,
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index 6e968d58631..c128872be07 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -109,7 +109,7 @@ static BMEdge *bmo_edge_copy(BMOperator *op,
BMO_slot_map_elem_insert(op, slot_edgemap_out, e_src, e_dst);
BMO_slot_map_elem_insert(op, slot_edgemap_out, e_dst, e_src);
- /* add to new/old edge map if necassary */
+ /* Add to new/old edge map if necessary. */
if (rlen < 2) {
/* not sure what non-manifold cases of greater than three
* radial should do. */
diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c
index 3aad37b3b02..df15778558b 100644
--- a/source/blender/bmesh/operators/bmo_fill_grid.c
+++ b/source/blender/bmesh/operators/bmo_fill_grid.c
@@ -326,8 +326,8 @@ static void bm_grid_fill_array(BMesh *bm,
v = BM_vert_create(bm, co, NULL, BM_CREATE_NOP);
v_grid[(y * xtot) + x] = v;
- /* interpolate only along one axis, this could be changed
- * but from user pov gives predictable results since these are selected loop */
+ /* Interpolate only along one axis, this could be changed
+ * but from user POV gives predictable results since these are selected loop. */
if (use_vert_interp) {
const float *w = weight_table[XY(x, y)];
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index 009c4f1f2c5..3869a0678e2 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -967,7 +967,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
is_mid = false;
}
- /* distable gives odd results at times, see T39288. */
+ /* Disable since this gives odd results at times, see T39288. */
#if 0
else if (compare_v3v3(f_a->no, f_b->no, 0.001f) == false) {
/* epsilon increased to fix T32329. */
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 1da4be57568..086114f64e9 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -66,7 +66,7 @@ static float quad_calc_error(const float v1[3],
error += diff;
}
- /* Colinearity */
+ /* Co-linearity */
{
float edge_vecs[4][3];
float diff;
diff --git a/source/blender/bmesh/operators/bmo_normals.c b/source/blender/bmesh/operators/bmo_normals.c
index 8e7bfbb649d..3311ffefb0d 100644
--- a/source/blender/bmesh/operators/bmo_normals.c
+++ b/source/blender/bmesh/operators/bmo_normals.c
@@ -29,7 +29,7 @@
#include "intern/bmesh_operators_private.h" /* own include */
-/********* righthand faces implementation ****** */
+/********* Right-hand faces implementation ****** */
#define FACE_FLAG (1 << 0)
#define FACE_FLIP (1 << 1)
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index d661859c8e3..8e088683d62 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -962,7 +962,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
BM_mesh_calc_uvs_sphere(bm, FACE_MARK, cd_loop_uv_offset);
}
- /* and now do imat */
+ /* Now apply the inverse matrix. */
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BMO_vert_flag_test(bm, eve, VERT_MARK)) {
mul_m4_v3(mat, eve->co);
@@ -1585,9 +1585,9 @@ void BM_mesh_calc_uvs_cone(BMesh *bm,
float inv_mat[4][4];
int loop_index;
- /* Transform the upvector like we did the cone itself, without location. */
+ /* Transform the up-vector like we did the cone itself, without location. */
mul_mat3_m4_v3(mat, local_up);
- /* Remove global scaling... */
+ /* Remove global scaling. */
normalize_v3(local_up);
invert_m4_m4(inv_mat, mat);
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index 02f17ea5d4a..361b10520da 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -387,7 +387,7 @@ void bmo_average_vert_facedata_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMIter iter;
BMVert *v;
- BMLoop *l /* , *firstl = NULL */;
+ BMLoop *l;
CDBlockBytes min, max;
int i;
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 8b2f9478aab..be996e6ffe4 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -51,13 +51,13 @@ typedef struct SubDParams {
BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */
float fractal_ofs[3];
- /* rumtime storage for shape key */
+ /* Runtime storage for shape key. */
struct {
int cd_vert_shape_offset;
int cd_vert_shape_offset_tmp;
int totlayer;
- /* shapekey holding displaced vertex coordinates for current geometry */
+ /* Shape-key holding displaced vertex coordinates for current geometry. */
int tmpkey;
} shape_info;
@@ -1094,7 +1094,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
}
- /* obvously don't test for other patterns matching */
+ /* Obviously don't test for other patterns matching. */
continue;
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index cd12a260f82..0de909b5556 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -235,7 +235,7 @@ typedef struct BoundVert {
/** Is this boundvert the side of the custom profile's start. */
bool is_profile_start;
char _pad[3];
- /** Length of seam starting from current boundvert to next boundvert with ccw ordering. */
+ /** Length of seam starting from current boundvert to next boundvert with CCW ordering. */
int seam_len;
/** Same as seam_len but defines length of sharp edges. */
int sharp_len;
@@ -807,6 +807,9 @@ static bool contig_ldata_across_edge(BMesh *bm, BMEdge *e, BMFace *f1, BMFace *f
}
BMVert *v1 = lef1->v;
BMVert *v2 = lef2->v;
+ if (v1 == v2) {
+ return false;
+ }
BLI_assert((v1 == e->v1 && v2 == e->v2) || (v1 == e->v2 && v2 == e->v1));
UNUSED_VARS_NDEBUG(v1, v2);
BMLoop *lv1f1 = lef1;
@@ -1958,7 +1961,7 @@ static bool make_unit_square_map(const float va[3],
/**
* Like make_unit_square_map, but this one makes a matrix that transforms the
* (1,1,1) corner of a unit cube into an arbitrary corner with corner vert d
- * and verts around it a, b, c (in ccw order, viewed from d normal dir).
+ * and verts around it a, b, c (in CCW order, viewed from d normal dir).
* The matrix mat is calculated to map:
* (1,0,0) -> va
* (0,1,0) -> vb
@@ -1966,9 +1969,9 @@ static bool make_unit_square_map(const float va[3],
* (1,1,1) -> vd
* We want M to make M*A=B where A has the left side above, as columns
* and B has the right side as columns - both extended into homogeneous coords.
- * So M = B*(Ainverse). Doing Ainverse by hand gives the code below.
- * The cols of M are 1/2{va-vb+vc-vd}, 1/2{-va+vb-vc+vd}, 1/2{-va-vb+vc+vd},
- * and 1/2{va+vb+vc-vd}
+ * So `M = B*(Ainverse)`. Doing `Ainverse` by hand gives the code below.
+ * The cols of M are `1/2{va-vb+vc-vd}`, `1/2{-va+vb-vc+vd}`, `1/2{-va-vb+vc+vd}`,
+ * and `1/2{va+vb+vc-vd}`
* and Blender matrices have cols at m[i][*].
*/
static void make_unit_cube_map(
@@ -3433,7 +3436,7 @@ static EdgeHalf *next_edgehalf_bev(BevelParams *bp,
}
normalize_v3(dir_new_edge);
- /* Use this edge if it is the most parallel to the orignial so far. */
+ /* Use this edge if it is the most parallel to the original so far. */
float new_dot = dot_v3v3(dir_new_edge, dir_start_edge);
if (new_dot > best_dot) {
second_best_dot = best_dot; /* For remembering if the choice was too close. */
@@ -4674,7 +4677,7 @@ static VMesh *pipe_adj_vmesh(BevelParams *bp, BevVert *bv, BoundVert *vpipe)
f = (float)k / (float)ns; /* Ring runs along the pipe, so segment is used here. */
}
- /* Place the vertex by interpolatin between the two profile points using the factor. */
+ /* Place the vertex by interpolating between the two profile points using the factor. */
interp_v3_v3v3(mesh_vert(vm, i, j, k)->co, profile_point_pipe1, profile_point_pipe2, f);
}
else {
@@ -6375,7 +6378,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
go_ccw = (e->fnext != f);
}
else {
- go_ccw = true; /* Going ccw around bv to trace this corner. */
+ go_ccw = true; /* Going CCW around bv to trace this corner. */
}
}
else if (eprev->prev == e) {
@@ -6385,7 +6388,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
/* Edges in face are non-contiguous in our ordering around bv.
* Which way should we go when going from eprev to e? */
if (count_ccw_edges_between(eprev, e) < count_ccw_edges_between(e, eprev)) {
- /* Go counterclockewise from eprev to e. */
+ /* Go counter-clockwise from eprev to e. */
go_ccw = true;
}
else {
@@ -6419,7 +6422,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
BLI_array_append(ee, bme);
}
while (v != vend) {
- /* Check for special case: multisegment 3rd face opposite a beveled edge with no vmesh. */
+ /* Check for special case: multi-segment 3rd face opposite a beveled edge with no vmesh. */
bool corner3special = (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev);
if (go_ccw) {
int i = v->index;
@@ -7227,17 +7230,17 @@ static void set_profile_spacing(BevelParams *bp, ProfileSpacing *pro_spacing, bo
* B
* </pre>
*
- * where edges are A, B, and C, following a face around vertices a, b, c, d.
- * th1 is angle abc and th2 is angle bcd;
- * and the argument EdgeHalf eb is B, going from b to c.
+ * where edges are A, B, and C, following a face around vertices `a, b, c, d`.
+ * `th1` is angle `abc` and th2 is angle `bcd`;
+ * and the argument `EdgeHalf eb` is B, going from b to c.
* In general case, edge offset specs for A, B, C have
- * the form ka*t, kb*t, kc*t where ka, kb, kc are some factors
+ * the form `ka*t`, `kb*t`, `kc*t` where `ka`, `kb`, `kc` are some factors
* (may be 0) and t is the current bp->offset.
* We want to calculate t at which the clone of B parallel
* to it collapses. This can be calculated using trig.
* Another case of geometry collision that can happen is
- * When B slides along A because A is unbeveled.
- * Then it might collide with a. Similarly for B sliding along C.
+ * When B slides along A because A is un-beveled.
+ * Then it might collide with a. Similarly for B sliding along C.
*/
static float geometry_collide_offset(BevelParams *bp, EdgeHalf *eb)
{
@@ -7566,7 +7569,7 @@ void BM_mesh_bevel(BMesh *bm,
}
}
- /* Perhaps clamp offset to avoid geometry colliisions. */
+ /* Perhaps clamp offset to avoid geometry collisions. */
if (limit_offset) {
bevel_limit_offset(&bp, bm);
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 60c49587387..92ca8e38737 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -294,8 +294,7 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
/* subtract existing cost to further differentiate edges from one another
*
* keep topology cost below 0.0 so their values don't interfere with quadric cost,
- * (and they get handled first).
- * */
+ * (and they get handled first). */
if (vweights == NULL) {
cost = bm_decim_build_edge_cost_single_squared__topology(e) - cost;
}
@@ -1319,9 +1318,9 @@ void BM_mesh_decimate_collapse(BMesh *bm,
UNUSED_VARS(do_triangulate);
#endif
- /* alloc vars */
+ /* Allocate variables. */
vquadrics = MEM_callocN(sizeof(Quadric) * bm->totvert, __func__);
- /* since some edges may be degenerate, we might be over allocing a little here */
+ /* Since some edges may be degenerate, we might be over allocating a little here. */
eheap = BLI_heap_new_ex(bm->totedge);
eheap_table = MEM_mallocN(sizeof(HeapNode *) * bm->totedge, __func__);
tot_edge_orig = bm->totedge;
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index 94a578fe1d7..2254b46f860 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -188,7 +188,7 @@ static void mul_v2_m3v3_center(float r[2],
static bool bm_loop_collapse_is_degenerate(BMLoop *l_ear)
{
- /* calculate relative to the centeral vertex for higher precision */
+ /* Calculate relative to the central vertex for higher precision. */
const float *center = l_ear->v->co;
float tri_2d[3][2];
diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c
index 1ab37ec0684..51af4d24e52 100644
--- a/source/blender/bmesh/tools/bmesh_edgenet.c
+++ b/source/blender/bmesh/tools/bmesh_edgenet.c
@@ -295,7 +295,7 @@ static LinkNode *bm_edgenet_path_calc(BMEdge *e,
vn_1->flag = vn_2->flag = (f_index == -1) ? VNINFO_FLAG_IS_MIXFACE : 0;
- /* prime the searchlist */
+ /* Prime the search-list. */
BLI_linklist_prepend_pool(&v_ls_prev, e->v1, path_pool);
BLI_linklist_prepend_pool(&v_ls_prev, e->v2, path_pool);
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index db05abe0e48..81b016e9601 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -1036,7 +1036,7 @@ bool BM_mesh_intersect(BMesh *bm,
#endif
if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE) {
- /* keep original geometrty for raycast callbacks */
+ /* Keep original geometry for ray-cast callbacks. */
float **cos;
int i, j;
@@ -1546,7 +1546,7 @@ bool BM_mesh_intersect(BMesh *bm,
bool do_remove, do_flip;
{
- /* for now assyme this is an OK face to test with (not degenerate!) */
+ /* For now assume this is an OK face to test with (not degenerate!) */
BMFace *f = ftable[groups_array[fg]];
float co[3];
int hits;
diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h
index 79c1ebcfe9f..6c8d372f587 100644
--- a/source/blender/compositor/COM_compositor.h
+++ b/source/blender/compositor/COM_compositor.h
@@ -268,8 +268,8 @@ extern "C" {
* When an ExecutionGroup schedules a Chunk the schedule method of the WorkScheduler
* The Workscheduler determines if the chunk can be run on an OpenCLDevice
* (and that there are available OpenCLDevice).
- * If this is the case the chunk will be added to the worklist for OpenCLDevice's
- * otherwise the chunk will be added to the worklist of CPUDevices.
+ * If this is the case the chunk will be added to the work-list for OpenCLDevice's
+ * otherwise the chunk will be added to the work-list of CPUDevices.
*
* A thread will read the work-list and sends a workpackage to its device.
*
@@ -298,7 +298,7 @@ extern "C" {
/**
* \brief The main method that is used to execute the compositor tree.
- * It can be executed during editing (blenkernel/node.c) or rendering
+ * It can be executed during editing (blenkernel/node.cc) or rendering
* (renderer/pipeline.c)
*
* \param rd: [struct RenderData]
diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp
index 3c2bf0aad07..92b334fddb9 100644
--- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp
+++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cpp
@@ -32,9 +32,9 @@ void ColorCorrectionNode::convertToOperations(NodeConverter &converter,
ColorCorrectionOperation *operation = new ColorCorrectionOperation();
operation->setData((NodeColorCorrection *)editorNode->storage);
- operation->setRedChannelEnabled((editorNode->custom1 & 1) > 0);
- operation->setGreenChannelEnabled((editorNode->custom1 & 2) > 0);
- operation->setBlueChannelEnabled((editorNode->custom1 & 4) > 0);
+ operation->setRedChannelEnabled((editorNode->custom1 & 1) != 0);
+ operation->setGreenChannelEnabled((editorNode->custom1 & 2) != 0);
+ operation->setBlueChannelEnabled((editorNode->custom1 & 4) != 0);
converter.addOperation(operation);
converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp
index 4e81a412c29..13bdabcdfd8 100644
--- a/source/blender/compositor/nodes/COM_KeyingNode.cpp
+++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp
@@ -239,7 +239,7 @@ void KeyingNode::convertToOperations(NodeConverter &converter,
converter.mapInputSocket(inputScreen, keyingOperation->getInputSocket(1));
if (keying_data->blur_pre) {
- /* chroma preblur operation for input of keying operation */
+ /* Chroma pre-blur operation for input of keying operation. */
NodeOperationOutput *preBluredImage = setupPreBlur(
converter, inputImage, keying_data->blur_pre);
converter.addLink(preBluredImage, keyingOperation->getInputSocket(0));
diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h
index 01ffa026152..2d775bdf738 100644
--- a/source/blender/compositor/operations/COM_BokehImageOperation.h
+++ b/source/blender/compositor/operations/COM_BokehImageOperation.h
@@ -55,7 +55,7 @@ class BokehImageOperation : public NodeOperation {
NodeBokehImage *m_data;
/**
- * \brief precalced center of the image
+ * \brief precalculate center of the image
*/
float m_center[2];
@@ -87,7 +87,7 @@ class BokehImageOperation : public NodeOperation {
/**
* \brief determine the coordinate of a flap corner.
*
- * \param r: result in bokehimage space are stored [x,y]
+ * \param r: result in bokeh-image space are stored [x,y]
* \param flapNumber: the flap number to calculate
* \param distance: the lens distance is used to simulate lens shifts
*/
diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp
index 29e18047578..52de0198a00 100644
--- a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp
+++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp
@@ -61,11 +61,10 @@ void ChromaMatteOperation::executePixelSampled(float output[4],
this->m_inputImageProgram->readSampled(inImage, x, y, sampler);
/* Store matte(alpha) value in [0] to go with
- * COM_SetAlphaMultiplyOperation and the Value output.
- */
+ * #COM_SetAlphaMultiplyOperation and the Value output. */
- /* Algorithm from book "Video Demistified," does not include the spill reduction part */
- /* find theta, the angle that the color space should be rotated based on key */
+ /* Algorithm from book "Video Demystified", does not include the spill reduction part. */
+ /* Find theta, the angle that the color space should be rotated based on key. */
/* rescale to -1.0..1.0 */
// inImage[0] = (inImage[0] * 2.0f) - 1.0f; // UNUSED
diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp
index 07466cdeccd..ccd291697cf 100644
--- a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp
+++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp
@@ -49,7 +49,7 @@ void CryptomatteOperation::executePixel(float output[4], int x, int y, void *dat
for (size_t i = 0; i < inputs.size(); i++) {
inputs[i]->read(input, x, y, data);
if (i == 0) {
- /* Write the frontmost object as false color for picking. */
+ /* Write the front-most object as false color for picking. */
output[0] = input[0];
uint32_t m3hash;
::memcpy(&m3hash, &input[0], sizeof(uint32_t));
diff --git a/source/blender/compositor/operations/COM_DotproductOperation.cpp b/source/blender/compositor/operations/COM_DotproductOperation.cpp
index 750e4308d11..5914be21453 100644
--- a/source/blender/compositor/operations/COM_DotproductOperation.cpp
+++ b/source/blender/compositor/operations/COM_DotproductOperation.cpp
@@ -39,7 +39,7 @@ void DotproductOperation::deinitExecution()
this->m_input2Operation = nullptr;
}
-/** \todo: current implementation is the inverse of a dotproduct. not 'logically' correct
+/** \todo current implementation is the inverse of a dot-product. not 'logically' correct
*/
void DotproductOperation::executePixelSampled(float output[4],
float x,
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
index fbbd373ba09..b548a684ba5 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
@@ -1256,7 +1256,7 @@ void DoubleEdgeMaskOperation::doDoubleEdgeMask(float *imask, float *omask, float
*
* Each version has slightly different criteria for detecting an edge pixel.
*/
- if (this->m_adjecentOnly) { // if "adjacent only" inner edge mode is turned on
+ if (this->m_adjacentOnly) { // if "adjacent only" inner edge mode is turned on
if (this->m_keepInside) { // if "keep inside" buffer edge mode is turned on
do_adjacentKeepBorders(t, rw, limask, lomask, lres, res, rsize);
}
@@ -1313,7 +1313,7 @@ DoubleEdgeMaskOperation::DoubleEdgeMaskOperation()
this->addOutputSocket(COM_DT_VALUE);
this->m_inputInnerMask = nullptr;
this->m_inputOuterMask = nullptr;
- this->m_adjecentOnly = false;
+ this->m_adjacentOnly = false;
this->m_keepInside = false;
this->setComplex(true);
}
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h
index e53aa7eb8aa..813f5009815 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h
@@ -27,7 +27,7 @@ class DoubleEdgeMaskOperation : public NodeOperation {
*/
SocketReader *m_inputOuterMask;
SocketReader *m_inputInnerMask;
- bool m_adjecentOnly;
+ bool m_adjacentOnly;
bool m_keepInside;
float *m_cachedInstance;
@@ -56,9 +56,9 @@ class DoubleEdgeMaskOperation : public NodeOperation {
ReadBufferOperation *readOperation,
rcti *output);
- void setAdjecentOnly(bool adjecentOnly)
+ void setAdjecentOnly(bool adjacentOnly)
{
- this->m_adjecentOnly = adjecentOnly;
+ this->m_adjacentOnly = adjacentOnly;
}
void setKeepInside(bool keepInside)
{
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
index c47d3b52beb..4d3efec7c85 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
@@ -42,7 +42,8 @@ void *GaussianAlphaXBlurOperation::initializeTileData(rcti * /*rect*/)
void GaussianAlphaXBlurOperation::initExecution()
{
- /* BlurBaseOperation::initExecution(); */ /* until we suppoer size input - comment this */
+ /* Until we support size input - comment this. */
+ // BlurBaseOperation::initExecution();
initMutex();
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
index 7a0dff73941..a722a879b8d 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
@@ -42,7 +42,8 @@ void *GaussianAlphaYBlurOperation::initializeTileData(rcti * /*rect*/)
void GaussianAlphaYBlurOperation::initExecution()
{
- /* BlurBaseOperation::initExecution(); */ /* until we suppoer size input - comment this */
+ /* Until we support size input - comment this. */
+ // BlurBaseOperation::initExecution();
initMutex();
diff --git a/source/blender/compositor/operations/COM_MixOperation.cpp b/source/blender/compositor/operations/COM_MixOperation.cpp
index 948e69bf8eb..76a66727a75 100644
--- a/source/blender/compositor/operations/COM_MixOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixOperation.cpp
@@ -705,7 +705,7 @@ void MixMultiplyOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
-/* ******** Mix Ovelray Operation ******** */
+/* ******** Mix Overlay Operation ******** */
MixOverlayOperation::MixOverlayOperation()
{
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h
index 3870593b423..cb8816b93b3 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.h
+++ b/source/blender/compositor/operations/COM_TonemapOperation.h
@@ -22,7 +22,7 @@
#include "DNA_node_types.h"
/**
- * \brief temporarily storage during execution of Tonemap
+ * \brief temporarily storage during execution of Tone-map
* \ingroup operation
*/
typedef struct AvgLogLum {
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
index f7b908deaf4..d6894dfc8ad 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
@@ -589,7 +589,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
printf("Found uninitialized speed in vector buffer... fixed.\n");
}
- /* min speed? then copy speedbuffer to recalculate speed vectors */
+ /* Min speed? then copy speed-buffer to recalculate speed vectors. */
if (nbd->minspeed) {
float minspeed = (float)nbd->minspeed;
float minspeedsq = minspeed * minspeed;
@@ -619,7 +619,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
SWAP(float *, minvecbufrect, vecbufrect);
}
- /* make vertex buffer with averaged speed and zvalues */
+ /* Make vertex buffer with averaged speed and Z-values. */
rectvz = (float *)MEM_callocN(sizeof(float[4]) * (xsize + 1) * (ysize + 1), "vertices");
dvz = rectvz;
for (y = 0; y <= ysize; y++) {
@@ -728,7 +728,8 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
antialias_tagbuf(xsize, ysize, rectmove);
- /* has to become static, the init-jit calls a random-seed, screwing up texture noise node */
+ /* Has to become static, the jitter initialization calls a random-seed,
+ * screwing up texture noise node. */
if (firsttime) {
firsttime = 0;
BLI_jitter_init(jit, 256);
diff --git a/source/blender/datatoc/CMakeLists.txt b/source/blender/datatoc/CMakeLists.txt
index 27dc01f1750..8411a1a468e 100644
--- a/source/blender/datatoc/CMakeLists.txt
+++ b/source/blender/datatoc/CMakeLists.txt
@@ -53,7 +53,7 @@ if(NOT WITH_HEADLESS)
include_directories(${PNG_INCLUDE_DIRS})
if(NOT APPLE)
- # APPLE plaform uses full paths for linking libraries.
+ # APPLE platform uses full paths for linking libraries.
link_directories(${PNG_LIBPATH} ${ZLIB_LIBPATH})
endif()
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index c3304cd80ff..d8dc66883a0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -178,7 +178,7 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
if (id_node->components.is_empty() && deg_copy_on_write_is_needed(id_type)) {
ComponentNode *comp_cow = id_node->add_component(NodeType::COPY_ON_WRITE);
OperationNode *op_cow = comp_cow->add_operation(
- function_bind(deg_evaluate_copy_on_write, _1, id_node),
+ [id_node](::Depsgraph *depsgraph) { deg_evaluate_copy_on_write(depsgraph, id_node); },
OperationCode::COPY_ON_WRITE,
"",
-1);
@@ -696,7 +696,9 @@ void DepsgraphNodeBuilder::build_object(int base_index,
add_operation_node(&object->id,
NodeType::SYNCHRONIZATION,
OperationCode::SYNCHRONIZE_TO_ORIGINAL,
- function_bind(BKE_object_sync_to_original, _1, object_cow));
+ [object_cow](::Depsgraph *depsgraph) {
+ BKE_object_sync_to_original(depsgraph, object_cow);
+ });
}
void DepsgraphNodeBuilder::build_object_from_layer(int base_index,
@@ -725,16 +727,15 @@ void DepsgraphNodeBuilder::build_object_flags(int base_index,
Object *object_cow = get_cow_datablock(object);
const bool is_from_set = (linked_state == DEG_ID_LINKED_VIA_SET);
/* TODO(sergey): Is this really best component to be used? */
- add_operation_node(&object->id,
- NodeType::OBJECT_FROM_LAYER,
- OperationCode::OBJECT_BASE_FLAGS,
- function_bind(BKE_object_eval_eval_base_flags,
- _1,
- scene_cow,
- view_layer_index_,
- object_cow,
- base_index,
- is_from_set));
+ add_operation_node(
+ &object->id,
+ NodeType::OBJECT_FROM_LAYER,
+ OperationCode::OBJECT_BASE_FLAGS,
+ [view_layer_index = view_layer_index_, scene_cow, object_cow, base_index, is_from_set](
+ ::Depsgraph *depsgraph) {
+ BKE_object_eval_eval_base_flags(
+ depsgraph, scene_cow, view_layer_index, object_cow, base_index, is_from_set);
+ });
}
void DepsgraphNodeBuilder::build_object_proxy_from(Object *object, bool is_object_visible)
@@ -853,34 +854,38 @@ void DepsgraphNodeBuilder::build_object_transform(Object *object)
op_node = add_operation_node(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_INIT);
op_node->set_as_entry();
/* Local transforms (from transform channels - loc/rot/scale + deltas). */
- add_operation_node(&object->id,
- NodeType::TRANSFORM,
- OperationCode::TRANSFORM_LOCAL,
- function_bind(BKE_object_eval_local_transform, _1, ob_cow));
+ add_operation_node(
+ &object->id,
+ NodeType::TRANSFORM,
+ OperationCode::TRANSFORM_LOCAL,
+ [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_local_transform(depsgraph, ob_cow); });
/* Object parent. */
if (object->parent != nullptr) {
- add_operation_node(&object->id,
- NodeType::TRANSFORM,
- OperationCode::TRANSFORM_PARENT,
- function_bind(BKE_object_eval_parent, _1, ob_cow));
+ add_operation_node(
+ &object->id,
+ NodeType::TRANSFORM,
+ OperationCode::TRANSFORM_PARENT,
+ [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_parent(depsgraph, ob_cow); });
}
/* Object constraints. */
if (object->constraints.first != nullptr) {
build_object_constraints(object);
}
/* Rest of transformation update. */
- add_operation_node(&object->id,
- NodeType::TRANSFORM,
- OperationCode::TRANSFORM_EVAL,
- function_bind(BKE_object_eval_uber_transform, _1, ob_cow));
+ add_operation_node(
+ &object->id,
+ NodeType::TRANSFORM,
+ OperationCode::TRANSFORM_EVAL,
+ [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_uber_transform(depsgraph, ob_cow); });
/* Operation to take of rigid body simulation. soft bodies and other friends
* in the context of point cache invalidation. */
add_operation_node(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT);
/* Object transform is done. */
- op_node = add_operation_node(&object->id,
- NodeType::TRANSFORM,
- OperationCode::TRANSFORM_FINAL,
- function_bind(BKE_object_eval_transform_final, _1, ob_cow));
+ op_node = add_operation_node(
+ &object->id,
+ NodeType::TRANSFORM,
+ OperationCode::TRANSFORM_FINAL,
+ [ob_cow](::Depsgraph *depsgraph) { BKE_object_eval_transform_final(depsgraph, ob_cow); });
op_node->set_as_exit();
}
@@ -904,12 +909,14 @@ void DepsgraphNodeBuilder::build_object_transform(Object *object)
void DepsgraphNodeBuilder::build_object_constraints(Object *object)
{
/* create node for constraint stack */
- add_operation_node(
- &object->id,
- NodeType::TRANSFORM,
- OperationCode::TRANSFORM_CONSTRAINTS,
- function_bind(
- BKE_object_eval_constraints, _1, get_cow_datablock(scene_), get_cow_datablock(object)));
+ Scene *scene_cow = get_cow_datablock(scene_);
+ Object *object_cow = get_cow_datablock(object);
+ add_operation_node(&object->id,
+ NodeType::TRANSFORM,
+ OperationCode::TRANSFORM_CONSTRAINTS,
+ [scene_cow, object_cow](::Depsgraph *depsgraph) {
+ BKE_object_eval_constraints(depsgraph, scene_cow, object_cow);
+ });
}
void DepsgraphNodeBuilder::build_object_pointcache(Object *object)
@@ -922,7 +929,9 @@ void DepsgraphNodeBuilder::build_object_pointcache(Object *object)
add_operation_node(&object->id,
NodeType::POINT_CACHE,
OperationCode::POINT_CACHE_RESET,
- function_bind(BKE_object_eval_ptcache_reset, _1, scene_cow, object_cow));
+ [scene_cow, object_cow](::Depsgraph *depsgraph) {
+ BKE_object_eval_ptcache_reset(depsgraph, scene_cow, object_cow);
+ });
}
/**
@@ -950,10 +959,10 @@ void DepsgraphNodeBuilder::build_animdata(ID *id)
operation_node = add_operation_node(id, NodeType::ANIMATION, OperationCode::ANIMATION_ENTRY);
operation_node->set_as_entry();
/* All the evaluation nodes. */
- add_operation_node(id,
- NodeType::ANIMATION,
- OperationCode::ANIMATION_EVAL,
- function_bind(BKE_animsys_eval_animdata, _1, id_cow));
+ add_operation_node(
+ id, NodeType::ANIMATION, OperationCode::ANIMATION_EVAL, [id_cow](::Depsgraph *depsgraph) {
+ BKE_animsys_eval_animdata(depsgraph, id_cow);
+ });
/* Explicit exit operation. */
operation_node = add_operation_node(id, NodeType::ANIMATION, OperationCode::ANIMATION_EXIT);
operation_node->set_as_exit();
@@ -989,10 +998,11 @@ void DepsgraphNodeBuilder::build_animation_images(ID *id)
{
if (BKE_image_user_id_has_animation(id)) {
ID *id_cow = get_cow_id(id);
- add_operation_node(id,
- NodeType::IMAGE_ANIMATION,
- OperationCode::IMAGE_ANIMATION,
- function_bind(BKE_image_user_id_eval_animation, _1, id_cow));
+ add_operation_node(
+ id,
+ NodeType::IMAGE_ANIMATION,
+ OperationCode::IMAGE_ANIMATION,
+ [id_cow](::Depsgraph *depsgraph) { BKE_image_user_id_eval_animation(depsgraph, id_cow); });
}
}
@@ -1020,12 +1030,15 @@ void DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcurve, int driver_index
* has not yet been allocated at this point we can't. As a workaround
* the animation systems allocates an array so we can do a fast lookup
* with the driver index. */
- ensure_operation_node(id,
- NodeType::PARAMETERS,
- OperationCode::DRIVER,
- function_bind(BKE_animsys_eval_driver, _1, id_cow, driver_index, fcurve),
- fcurve->rna_path ? fcurve->rna_path : "",
- fcurve->array_index);
+ ensure_operation_node(
+ id,
+ NodeType::PARAMETERS,
+ OperationCode::DRIVER,
+ [id_cow, driver_index, fcurve](::Depsgraph *depsgraph) {
+ BKE_animsys_eval_driver(depsgraph, id_cow, driver_index, fcurve);
+ },
+ fcurve->rna_path ? fcurve->rna_path : "",
+ fcurve->array_index);
build_driver_variables(id, fcurve);
}
@@ -1103,10 +1116,11 @@ void DepsgraphNodeBuilder::build_world(World *world)
add_id_node(&world->id);
World *world_cow = get_cow_datablock(world);
/* Shading update. */
- add_operation_node(&world->id,
- NodeType::SHADING,
- OperationCode::WORLD_UPDATE,
- function_bind(BKE_world_eval, _1, world_cow));
+ add_operation_node(
+ &world->id,
+ NodeType::SHADING,
+ OperationCode::WORLD_UPDATE,
+ [world_cow](::Depsgraph *depsgraph) { BKE_world_eval(depsgraph, world_cow); });
build_idproperties(world->id.properties);
/* Animation. */
build_animdata(&world->id);
@@ -1142,16 +1156,19 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
* instead? */
/* Init/rebuild operation. */
- add_operation_node(&scene->id,
- NodeType::TRANSFORM,
- OperationCode::RIGIDBODY_REBUILD,
- function_bind(BKE_rigidbody_rebuild_sim, _1, scene_cow));
- /* Do-sim operation. */
- OperationNode *sim_node = add_operation_node(
+ add_operation_node(
&scene->id,
NodeType::TRANSFORM,
- OperationCode::RIGIDBODY_SIM,
- function_bind(BKE_rigidbody_eval_simulation, _1, scene_cow));
+ OperationCode::RIGIDBODY_REBUILD,
+ [scene_cow](::Depsgraph *depsgraph) { BKE_rigidbody_rebuild_sim(depsgraph, scene_cow); });
+ /* Do-sim operation. */
+ OperationNode *sim_node = add_operation_node(&scene->id,
+ NodeType::TRANSFORM,
+ OperationCode::RIGIDBODY_SIM,
+ [scene_cow](::Depsgraph *depsgraph) {
+ BKE_rigidbody_eval_simulation(depsgraph,
+ scene_cow);
+ });
sim_node->set_as_entry();
sim_node->set_as_exit();
sim_node->owner->entry_operation = sim_node;
@@ -1173,12 +1190,13 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
/* Create operation for flushing results. */
/* Object's transform component - where the rigidbody operation
* lives. */
- add_operation_node(
- &object->id,
- NodeType::TRANSFORM,
- OperationCode::RIGIDBODY_TRANSFORM_COPY,
- function_bind(
- BKE_rigidbody_object_sync_transforms, _1, scene_cow, get_cow_datablock(object)));
+ Object *object_cow = get_cow_datablock(object);
+ add_operation_node(&object->id,
+ NodeType::TRANSFORM,
+ OperationCode::RIGIDBODY_TRANSFORM_COPY,
+ [scene_cow, object_cow](::Depsgraph *depsgraph) {
+ BKE_rigidbody_object_sync_transforms(depsgraph, scene_cow, object_cow);
+ });
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
@@ -1219,9 +1237,10 @@ void DepsgraphNodeBuilder::build_particle_systems(Object *object, bool is_object
Object *ob_cow = get_cow_datablock(object);
OperationNode *op_node;
- op_node = add_operation_node(psys_comp,
- OperationCode::PARTICLE_SYSTEM_INIT,
- function_bind(BKE_particle_system_eval_init, _1, ob_cow));
+ op_node = add_operation_node(
+ psys_comp, OperationCode::PARTICLE_SYSTEM_INIT, [ob_cow](::Depsgraph *depsgraph) {
+ BKE_particle_system_eval_init(depsgraph, ob_cow);
+ });
op_node->set_as_entry();
/* Build all particle systems. */
LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
@@ -1278,7 +1297,9 @@ void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *particle_se
add_operation_node(&particle_settings->id,
NodeType::PARTICLE_SETTINGS,
OperationCode::PARTICLE_SETTINGS_RESET,
- function_bind(BKE_particle_settings_eval_reset, _1, particle_settings_cow));
+ [particle_settings_cow](::Depsgraph *depsgraph) {
+ BKE_particle_settings_eval_reset(depsgraph, particle_settings_cow);
+ });
op_node = add_operation_node(
&particle_settings->id, NodeType::PARTICLE_SETTINGS, OperationCode::PARTICLE_SETTINGS_EVAL);
op_node->set_as_exit();
@@ -1323,11 +1344,12 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob
op_node = add_operation_node(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
op_node->set_as_entry();
/* Geometry evaluation. */
- op_node = add_operation_node(
- &object->id,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- function_bind(BKE_object_eval_uber_data, _1, scene_cow, object_cow));
+ op_node = add_operation_node(&object->id,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [scene_cow, object_cow](::Depsgraph *depsgraph) {
+ BKE_object_eval_uber_data(depsgraph, scene_cow, object_cow);
+ });
op_node->set_as_exit();
/* Materials. */
build_materials(object->mat, object->totcol);
@@ -1337,10 +1359,11 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob
build_object_data_geometry_datablock((ID *)object->data, is_object_visible);
build_dimensions(object);
/* Batch cache. */
- add_operation_node(&object->id,
- NodeType::BATCH_CACHE,
- OperationCode::GEOMETRY_SELECT_UPDATE,
- function_bind(BKE_object_select_update, _1, object_cow));
+ add_operation_node(
+ &object->id,
+ NodeType::BATCH_CACHE,
+ OperationCode::GEOMETRY_SELECT_UPDATE,
+ [object_cow](::Depsgraph *depsgraph) { BKE_object_select_update(depsgraph, object_cow); });
}
void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool is_object_visible)
@@ -1368,7 +1391,9 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
op_node = add_operation_node(obdata,
NodeType::GEOMETRY,
OperationCode::GEOMETRY_EVAL,
- function_bind(BKE_mesh_eval_geometry, _1, (Mesh *)obdata_cow));
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_mesh_eval_geometry(depsgraph, (Mesh *)obdata_cow);
+ });
op_node->set_as_entry();
break;
}
@@ -1378,11 +1403,12 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
break;
}
case ID_CU: {
- op_node = add_operation_node(
- obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- function_bind(BKE_curve_eval_geometry, _1, (Curve *)obdata_cow));
+ op_node = add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow);
+ });
op_node->set_as_entry();
/* Make sure objects used for bevel.taper are in the graph.
* NOTE: This objects might be not linked to the scene. */
@@ -1399,22 +1425,25 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
break;
}
case ID_LT: {
- op_node = add_operation_node(
- obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- function_bind(BKE_lattice_eval_geometry, _1, (Lattice *)obdata_cow));
+ op_node = add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_lattice_eval_geometry(depsgraph, (Lattice *)obdata_cow);
+ });
op_node->set_as_entry();
break;
}
case ID_GD: {
/* GPencil evaluation operations. */
- op_node = add_operation_node(
- obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- function_bind(BKE_gpencil_frame_active_set, _1, (bGPdata *)obdata_cow));
+ op_node = add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_gpencil_frame_active_set(depsgraph,
+ (bGPdata *)obdata_cow);
+ });
op_node->set_as_entry();
break;
}
@@ -1430,11 +1459,12 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
}
case ID_VO: {
/* Volume frame update. */
- op_node = add_operation_node(
- obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- function_bind(BKE_volume_eval_geometry, _1, (Volume *)obdata_cow));
+ op_node = add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_volume_eval_geometry(depsgraph, (Volume *)obdata_cow);
+ });
op_node->set_as_entry();
break;
}
@@ -1450,7 +1480,9 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
add_operation_node(obdata,
NodeType::BATCH_CACHE,
OperationCode::GEOMETRY_SELECT_UPDATE,
- function_bind(BKE_object_data_select_update, _1, obdata_cow));
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_object_data_select_update(depsgraph, obdata_cow);
+ });
}
void DepsgraphNodeBuilder::build_armature(bArmature *armature)
@@ -1466,7 +1498,9 @@ void DepsgraphNodeBuilder::build_armature(bArmature *armature)
add_operation_node(&armature->id,
NodeType::ARMATURE,
OperationCode::ARMATURE_EVAL,
- function_bind(BKE_armature_refresh_layer_used, _1, armature_cow));
+ [armature_cow](::Depsgraph *depsgraph) {
+ BKE_armature_refresh_layer_used(depsgraph, armature_cow);
+ });
build_armature_bones(&armature->bonebase);
}
@@ -1506,7 +1540,7 @@ void DepsgraphNodeBuilder::build_light(Light *lamp)
add_operation_node(&lamp->id,
NodeType::SHADING,
OperationCode::LIGHT_UPDATE,
- function_bind(BKE_light_eval, _1, lamp_cow));
+ [lamp_cow](::Depsgraph *depsgraph) { BKE_light_eval(depsgraph, lamp_cow); });
}
void DepsgraphNodeBuilder::build_nodetree_socket(bNodeSocket *socket)
@@ -1534,7 +1568,6 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
}
/* nodetree itself */
add_id_node(&ntree->id);
- bNodeTree *ntree_cow = get_cow_datablock(ntree);
/* General parameters. */
build_parameters(&ntree->id);
build_idproperties(ntree->id.properties);
@@ -1542,12 +1575,7 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
build_animdata(&ntree->id);
/* Shading update. */
add_operation_node(&ntree->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
- /* NOTE: We really pass original and CoW node trees here, this is how the
- * callback works. Ideally we need to find a better way for that. */
- add_operation_node(&ntree->id,
- NodeType::SHADING_PARAMETERS,
- OperationCode::MATERIAL_UPDATE,
- function_bind(BKE_nodetree_shading_params_eval, _1, ntree_cow, ntree));
+ add_operation_node(&ntree->id, NodeType::SHADING_PARAMETERS, OperationCode::MATERIAL_UPDATE);
/* nodetree's nodes... */
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
@@ -1626,10 +1654,11 @@ void DepsgraphNodeBuilder::build_material(Material *material)
add_id_node(&material->id);
Material *material_cow = get_cow_datablock(material);
/* Shading update. */
- add_operation_node(&material->id,
- NodeType::SHADING,
- OperationCode::MATERIAL_UPDATE,
- function_bind(BKE_material_eval, _1, material_cow));
+ add_operation_node(
+ &material->id,
+ NodeType::SHADING,
+ OperationCode::MATERIAL_UPDATE,
+ [material_cow](::Depsgraph *depsgraph) { BKE_material_eval(depsgraph, material_cow); });
build_idproperties(material->id.properties);
/* Material animation. */
build_animdata(&material->id);
@@ -1714,7 +1743,9 @@ void DepsgraphNodeBuilder::build_cachefile(CacheFile *cache_file)
add_operation_node(cache_file_id,
NodeType::CACHE,
OperationCode::FILE_CACHE_UPDATE,
- function_bind(BKE_cachefile_eval, bmain_, _1, cache_file_cow));
+ [bmain = bmain_, cache_file_cow](::Depsgraph *depsgraph) {
+ BKE_cachefile_eval(bmain, depsgraph, cache_file_cow);
+ });
}
void DepsgraphNodeBuilder::build_mask(Mask *mask)
@@ -1729,15 +1760,16 @@ void DepsgraphNodeBuilder::build_mask(Mask *mask)
build_animdata(mask_id);
build_parameters(mask_id);
/* Animation based on mask's shapes. */
- add_operation_node(mask_id,
- NodeType::ANIMATION,
- OperationCode::MASK_ANIMATION,
- function_bind(BKE_mask_eval_animation, _1, mask_cow));
+ add_operation_node(
+ mask_id,
+ NodeType::ANIMATION,
+ OperationCode::MASK_ANIMATION,
+ [mask_cow](::Depsgraph *depsgraph) { BKE_mask_eval_animation(depsgraph, mask_cow); });
/* Final mask evaluation. */
- add_operation_node(mask_id,
- NodeType::PARAMETERS,
- OperationCode::MASK_EVAL,
- function_bind(BKE_mask_eval_update, _1, mask_cow));
+ add_operation_node(
+ mask_id, NodeType::PARAMETERS, OperationCode::MASK_EVAL, [mask_cow](::Depsgraph *depsgraph) {
+ BKE_mask_eval_update(depsgraph, mask_cow);
+ });
/* Build parents. */
LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
@@ -1781,12 +1813,16 @@ void DepsgraphNodeBuilder::build_movieclip(MovieClip *clip)
add_operation_node(clip_id,
NodeType::PARAMETERS,
OperationCode::MOVIECLIP_EVAL,
- function_bind(BKE_movieclip_eval_update, _1, bmain_, clip_cow));
+ [bmain = bmain_, clip_cow](::Depsgraph *depsgraph) {
+ BKE_movieclip_eval_update(depsgraph, bmain, clip_cow);
+ });
add_operation_node(clip_id,
NodeType::BATCH_CACHE,
OperationCode::MOVIECLIP_SELECT_UPDATE,
- function_bind(BKE_movieclip_eval_selection_update, _1, clip_cow));
+ [clip_cow](::Depsgraph *depsgraph) {
+ BKE_movieclip_eval_selection_update(depsgraph, clip_cow);
+ });
}
void DepsgraphNodeBuilder::build_lightprobe(LightProbe *probe)
@@ -1826,7 +1862,9 @@ void DepsgraphNodeBuilder::build_sound(bSound *sound)
add_operation_node(&sound->id,
NodeType::AUDIO,
OperationCode::SOUND_EVAL,
- function_bind(BKE_sound_evaluate, _1, bmain_, sound_cow));
+ [bmain = bmain_, sound_cow](::Depsgraph *depsgraph) {
+ BKE_sound_evaluate(depsgraph, bmain, sound_cow);
+ });
build_idproperties(sound->id.properties);
build_animdata(&sound->id);
build_parameters(&sound->id);
@@ -1849,7 +1887,9 @@ void DepsgraphNodeBuilder::build_simulation(Simulation *simulation)
add_operation_node(&simulation->id,
NodeType::SIMULATION,
OperationCode::SIMULATION_EVAL,
- function_bind(BKE_simulation_data_update, _1, scene_cow, simulation_cow));
+ [scene_cow, simulation_cow](::Depsgraph *depsgraph) {
+ BKE_simulation_data_update(depsgraph, scene_cow, simulation_cow);
+ });
}
void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
@@ -1865,7 +1905,9 @@ void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
add_operation_node(&scene->id,
NodeType::SEQUENCER,
OperationCode::SEQUENCES_EVAL,
- function_bind(BKE_scene_eval_sequencer_sequences, _1, scene_cow));
+ [scene_cow](::Depsgraph *depsgraph) {
+ BKE_scene_eval_sequencer_sequences(depsgraph, scene_cow);
+ });
/* Make sure data for sequences is in the graph. */
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
@@ -1904,7 +1946,9 @@ void DepsgraphNodeBuilder::build_scene_audio(Scene *scene)
add_operation_node(&scene->id,
NodeType::AUDIO,
OperationCode::AUDIO_VOLUME,
- function_bind(BKE_scene_update_tag_audio_volume, _1, scene_cow));
+ [scene_cow](::Depsgraph *depsgraph) {
+ BKE_scene_update_tag_audio_volume(depsgraph, scene_cow);
+ });
}
void DepsgraphNodeBuilder::build_scene_speakers(Scene * /*scene*/, ViewLayer *view_layer)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index 8ba4b4a427f..13caba67713 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -66,16 +66,18 @@ void DepsgraphNodeBuilder::build_pose_constraints(Object *object,
data.builder = this;
data.is_parent_visible = is_object_visible;
BKE_constraints_id_loop(&pchan->constraints, constraint_walk, &data);
+
/* Create node for constraint stack. */
+ Scene *scene_cow = get_cow_datablock(scene_);
+ Object *object_cow = get_cow_datablock(object);
add_operation_node(&object->id,
NodeType::BONE,
pchan->name,
OperationCode::BONE_CONSTRAINTS,
- function_bind(BKE_pose_constraints_evaluate,
- _1,
- get_cow_datablock(scene_),
- get_cow_datablock(object),
- pchan_index));
+ [scene_cow, object_cow, pchan_index](::Depsgraph *depsgraph) {
+ BKE_pose_constraints_evaluate(
+ depsgraph, scene_cow, object_cow, pchan_index);
+ });
}
/* IK Solver Eval Steps */
@@ -96,16 +98,17 @@ void DepsgraphNodeBuilder::build_ik_pose(Object *object, bPoseChannel *pchan, bC
int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
BLI_assert(rootchan_index != -1);
+
/* Operation node for evaluating/running IK Solver. */
+ Scene *scene_cow = get_cow_datablock(scene_);
+ Object *object_cow = get_cow_datablock(object);
add_operation_node(&object->id,
NodeType::EVAL_POSE,
rootchan->name,
OperationCode::POSE_IK_SOLVER,
- function_bind(BKE_pose_iktree_evaluate,
- _1,
- get_cow_datablock(scene_),
- get_cow_datablock(object),
- rootchan_index));
+ [scene_cow, object_cow, rootchan_index](::Depsgraph *depsgraph) {
+ BKE_pose_iktree_evaluate(depsgraph, scene_cow, object_cow, rootchan_index);
+ });
}
/* Spline IK Eval Steps */
@@ -130,15 +133,17 @@ void DepsgraphNodeBuilder::build_splineik_pose(Object *object,
* start. */
int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
BLI_assert(rootchan_index != -1);
+
+ Scene *scene_cow = get_cow_datablock(scene_);
+ Object *object_cow = get_cow_datablock(object);
add_operation_node(&object->id,
NodeType::EVAL_POSE,
rootchan->name,
OperationCode::POSE_SPLINE_IK_SOLVER,
- function_bind(BKE_pose_splineik_evaluate,
- _1,
- get_cow_datablock(scene_),
- get_cow_datablock(object),
- rootchan_index));
+ [scene_cow, object_cow, rootchan_index](::Depsgraph *depsgraph) {
+ BKE_pose_splineik_evaluate(
+ depsgraph, scene_cow, object_cow, rootchan_index);
+ });
}
/* Pose/Armature Bones Graph */
@@ -193,23 +198,30 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
op_node = add_operation_node(&object->id,
NodeType::EVAL_POSE,
OperationCode::POSE_INIT,
- function_bind(BKE_pose_eval_init, _1, scene_cow, object_cow));
+ [scene_cow, object_cow](::Depsgraph *depsgraph) {
+ BKE_pose_eval_init(depsgraph, scene_cow, object_cow);
+ });
op_node->set_as_entry();
op_node = add_operation_node(&object->id,
NodeType::EVAL_POSE,
OperationCode::POSE_INIT_IK,
- function_bind(BKE_pose_eval_init_ik, _1, scene_cow, object_cow));
+ [scene_cow, object_cow](::Depsgraph *depsgraph) {
+ BKE_pose_eval_init_ik(depsgraph, scene_cow, object_cow);
+ });
add_operation_node(&object->id,
NodeType::EVAL_POSE,
OperationCode::POSE_CLEANUP,
- function_bind(BKE_pose_eval_cleanup, _1, scene_cow, object_cow));
-
- op_node = add_operation_node(&object->id,
- NodeType::EVAL_POSE,
- OperationCode::POSE_DONE,
- function_bind(BKE_pose_eval_done, _1, object_cow));
+ [scene_cow, object_cow](::Depsgraph *depsgraph) {
+ BKE_pose_eval_cleanup(depsgraph, scene_cow, object_cow);
+ });
+
+ op_node = add_operation_node(
+ &object->id,
+ NodeType::EVAL_POSE,
+ OperationCode::POSE_DONE,
+ [object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_done(depsgraph, object_cow); });
op_node->set_as_exit();
/* Bones. */
int pchan_index = 0;
@@ -223,7 +235,9 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
NodeType::BONE,
pchan->name,
OperationCode::BONE_POSE_PARENT,
- function_bind(BKE_pose_eval_bone, _1, scene_cow, object_cow, pchan_index));
+ [scene_cow, object_cow, pchan_index](::Depsgraph *depsgraph) {
+ BKE_pose_eval_bone(depsgraph, scene_cow, object_cow, pchan_index);
+ });
/* NOTE: Dedicated noop for easier relationship construction. */
add_operation_node(&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_READY);
@@ -232,16 +246,20 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
NodeType::BONE,
pchan->name,
OperationCode::BONE_DONE,
- function_bind(BKE_pose_bone_done, _1, object_cow, pchan_index));
+ [object_cow, pchan_index](::Depsgraph *depsgraph) {
+ BKE_pose_bone_done(depsgraph, object_cow, pchan_index);
+ });
/* B-Bone shape computation - the real last step if present. */
if (check_pchan_has_bbone(object, pchan)) {
- op_node = add_operation_node(
- &object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_SEGMENTS,
- function_bind(BKE_pose_eval_bbone_segments, _1, object_cow, pchan_index));
+ op_node = add_operation_node(&object->id,
+ NodeType::BONE,
+ pchan->name,
+ OperationCode::BONE_SEGMENTS,
+ [object_cow, pchan_index](::Depsgraph *depsgraph) {
+ BKE_pose_eval_bbone_segments(
+ depsgraph, object_cow, pchan_index);
+ });
}
op_node->set_as_exit();
@@ -304,10 +322,11 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object, bool is_object_visibl
if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
BKE_pose_update_constraint_flags(object->pose);
}
- op_node = add_operation_node(&object->id,
- NodeType::EVAL_POSE,
- OperationCode::POSE_INIT,
- function_bind(BKE_pose_eval_proxy_init, _1, object_cow));
+ op_node = add_operation_node(
+ &object->id,
+ NodeType::EVAL_POSE,
+ OperationCode::POSE_INIT,
+ [object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_proxy_init(depsgraph, object_cow); });
op_node->set_as_entry();
int pchan_index = 0;
@@ -318,12 +337,14 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object, bool is_object_visibl
/* Bone is ready for solvers. */
add_operation_node(&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_READY);
/* Bone is fully evaluated. */
- op_node = add_operation_node(
- &object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_DONE,
- function_bind(BKE_pose_eval_proxy_copy_bone, _1, object_cow, pchan_index));
+ op_node = add_operation_node(&object->id,
+ NodeType::BONE,
+ pchan->name,
+ OperationCode::BONE_DONE,
+ [object_cow, pchan_index](::Depsgraph *depsgraph) {
+ BKE_pose_eval_proxy_copy_bone(
+ depsgraph, object_cow, pchan_index);
+ });
op_node->set_as_exit();
/* Custom properties. */
@@ -343,11 +364,14 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object, bool is_object_visibl
op_node = add_operation_node(&object->id,
NodeType::EVAL_POSE,
OperationCode::POSE_CLEANUP,
- function_bind(BKE_pose_eval_proxy_cleanup, _1, object_cow));
- op_node = add_operation_node(&object->id,
- NodeType::EVAL_POSE,
- OperationCode::POSE_DONE,
- function_bind(BKE_pose_eval_proxy_done, _1, object_cow));
+ [object_cow](::Depsgraph *depsgraph) {
+ BKE_pose_eval_proxy_cleanup(depsgraph, object_cow);
+ });
+ op_node = add_operation_node(
+ &object->id,
+ NodeType::EVAL_POSE,
+ OperationCode::POSE_DONE,
+ [object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_proxy_done(depsgraph, object_cow); });
op_node->set_as_exit();
}
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 b1fd86f13bc..29aa05b83db 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
@@ -160,11 +160,12 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
build_scene_sequencer(scene);
}
/* Collections. */
- add_operation_node(
- &scene->id,
- NodeType::LAYER_COLLECTIONS,
- OperationCode::VIEW_LAYER_EVAL,
- function_bind(BKE_layer_eval_view_layer_indexed, _1, scene_cow, view_layer_index_));
+ add_operation_node(&scene->id,
+ NodeType::LAYER_COLLECTIONS,
+ OperationCode::VIEW_LAYER_EVAL,
+ [view_layer_index = view_layer_index_, scene_cow](::Depsgraph *depsgraph) {
+ BKE_layer_eval_view_layer_indexed(depsgraph, scene_cow, view_layer_index);
+ });
/* Parameters evaluation for scene relations mainly. */
build_scene_compositor(scene);
build_scene_parameters(scene);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 463efe52375..96b4da34347 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1238,7 +1238,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
// TODO: loc vs rot vs scale?
if (&ct->tar->id == id) {
/* Constraint targeting own object:
- * - This case is fine IFF we're dealing with a bone
+ * - This case is fine IF we're dealing with a bone
* constraint pointing to its own armature. In that
* case, it's just transform -> bone.
* - If however it is a real self targeting case, just
@@ -1814,7 +1814,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
RELATION_FLAG_GODMODE);
}
- /* Final transform is whetever solver gave to us. */
+ /* Final transform is whatever the solver gave to us. */
if (object->rigidbody_object->type == RBO_TYPE_ACTIVE) {
/* We do not have to update the objects final transform after the simulation if it is
* passive or controlled by the animation system in blender.
@@ -2496,7 +2496,7 @@ void DepsgraphRelationBuilder::build_material(Material *material)
/* Animated / driven parameters (without nodetree). */
OperationKey material_key(&material->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
ComponentKey parameters_key(&material->id, NodeType::PARAMETERS);
- add_relation(parameters_key, material_key, "Material's paramters");
+ add_relation(parameters_key, material_key, "Material's parameters");
/* material's nodetree */
if (material->nodetree != nullptr) {
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 a0cbbbc163d..9afae0f2c22 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
@@ -184,7 +184,7 @@ static void deg_debug_graphviz_legend(DotExportContext &ctx)
std::stringstream ss;
ss << "<";
- ss << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">";
+ ss << R"(<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">)";
ss << "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>";
#ifdef COLOR_SCHEME_NODE_CLASS
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
index 0cdd627dd44..df343a3eb28 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
@@ -87,7 +87,7 @@ string gnuplotify_name(const string &name)
for (int i = 0; i < length; i++) {
const char ch = name[i];
if (ch == '_') {
- result += "\\\\\\";
+ result += R"(\\\)";
}
result += ch;
}
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index e472d82f2ee..34465c12914 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -193,6 +193,32 @@ bool deg_iterator_components_step(BLI_Iterator *iter)
}
}
+ /* The volume component. */
+ if (data->geometry_component_id == 2) {
+ data->geometry_component_id++;
+
+ /* Don't use a temporary object for this component, when the owner is a volume object. */
+ if (data->geometry_component_owner->type == OB_VOLUME) {
+ iter->current = data->geometry_component_owner;
+ return true;
+ }
+
+ const VolumeComponent *component = geometry_set->get_component_for_read<VolumeComponent>();
+ if (component != nullptr) {
+ const Volume *volume = component->get_for_read();
+
+ if (volume != nullptr) {
+ Object *temp_object = &data->temp_geometry_component_object;
+ *temp_object = *data->geometry_component_owner;
+ temp_object->type = OB_VOLUME;
+ temp_object->data = (void *)volume;
+ temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
+ iter->current = temp_object;
+ return true;
+ }
+ }
+ }
+
data->geometry_component_owner = nullptr;
return false;
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h
index 007236e7890..d16f5b9b5ce 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.h
@@ -46,7 +46,7 @@ class SceneBackup {
*
* NOTE: Scene can not disappear after relations update, because otherwise the entire dependency
* graph will be gone. This means we don't need to compare original scene pointer, or worry about
- * freeing those if they cant' be restored: we just copy them over to a new scene. */
+ * freeing those if they can't be restored: we just copy them over to a new scene. */
void *sound_scene;
void *playback_handle;
void *sound_scrub_handle;
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h
index c4d36685bb8..e2d3b3fc36f 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.h
+++ b/source/blender/depsgraph/intern/node/deg_node_id.h
@@ -88,7 +88,7 @@ struct IDNode : public Node {
* which could be "stale" pointer. */
uint id_orig_session_uuid;
- /* Evaluated datablock.
+ /* Evaluated data-block.
* Will be covered by the copy-on-write system if the ID Type needs it. */
ID *id_cow;
@@ -107,7 +107,7 @@ struct IDNode : public Node {
eDepsNode_LinkedState_Type linked_state;
- /* Indicates the datablock is visible in the evaluated scene. */
+ /* Indicates the data-block is visible in the evaluated scene. */
bool is_directly_visible;
/* For the collection type of ID, denotes whether collection was fully
diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
index b47e8c5f081..13a3f1766a9 100644
--- a/source/blender/draw/engines/eevee/eevee_cryptomatte.c
+++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
@@ -363,7 +363,7 @@ static void eevee_cryptomatte_download_buffer(EEVEE_Data *vedata, GPUFrameBuffer
download_buffer);
/* Integrate download buffer into the accum buffer.
- * The download buffer contains upto 3 floats per pixel (one float per cryptomatte layer.
+ * The download buffer contains up to 3 floats per pixel (one float per cryptomatte layer.
*
* NOTE: here we deviate from the cryptomatte standard. During integration the standard always
* sort the samples by its weight to make sure that samples with the lowest weight
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 47068d0b843..b453df284ed 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -130,7 +130,7 @@ EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *
}
EEVEE_ObjectKey key, *key_p;
- /* Small hack to avoid another comparisson. */
+ /* Small hack to avoid another comparison. */
key.ob = (Object *)((char *)ob + hair);
DupliObject *dup = DRW_object_get_dupli(ob);
if (dup) {
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index ca583143572..698b959f1a9 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -242,7 +242,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
{
- /* Perform min/max downsample */
+ /* Perform min/max down-sample. */
DRW_PASS_CREATE(psl->maxz_downlevel_ps, downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(EEVEE_shaders_effect_maxz_downlevel_sh_get(), psl->maxz_downlevel_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &txl->maxzbuffer);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index c6760de5cfa..802b47b61a4 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -319,7 +319,7 @@ static void eevee_draw_scene(void *vedata)
EEVEE_renderpasses_output_accumulate(sldata, vedata, false);
/* Transparent */
- /* TODO(fclem): should be its own Framebuffer.
+ /* TODO(fclem): should be its own Frame-buffer.
* This is needed because dualsource blending only works with 1 color buffer. */
GPU_framebuffer_texture_attach(fbl->main_color_fb, dtxl->depth, 0, 0);
GPU_framebuffer_bind(fbl->main_color_fb);
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 040aa8c8d9c..c4973dc2e8b 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -99,9 +99,9 @@ typedef struct EEVEE_LightBake {
GPUTexture *rt_color;
/** Target cube depth texture. */
GPUTexture *rt_depth;
- /** Target cube framebuffers. */
+ /** Target cube frame-buffers. */
GPUFrameBuffer *rt_fb[6];
- /** Storage framebuffer. */
+ /** Storage frame-buffer. */
GPUFrameBuffer *store_fb;
/** Cube render target resolution. */
int rt_res;
@@ -135,7 +135,7 @@ typedef struct EEVEE_LightBake {
int grid_curr;
/** The current light bounce being evaluated. */
int bounce_curr, bounce_len;
- /** Resolution of the Visibility shadowmap. */
+ /** Resolution of the Visibility shadow-map. */
float vis_res;
/** Result of previous light bounce. */
GPUTexture *grid_prev;
@@ -163,7 +163,7 @@ typedef struct EEVEE_LightBake {
/** For only handling the resources. */
bool resource_only;
bool own_resources;
- /** If the lightcache was created for baking, it's first owned by the baker. */
+ /** If the light-cache was created for baking, it's first owned by the baker. */
bool own_light_cache;
/** ms. delay the start of the baking to not slowdown interactions (TODO remove) */
int delay;
@@ -907,7 +907,7 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
lbake->sldata = sldata;
- /* Disable all effects BUT high bitdepth shadows. */
+ /* Disable all effects BUT high bit-depth shadows. */
scene_eval->eevee.flag &= SCE_EEVEE_SHADOW_HIGH_BITDEPTH;
scene_eval->eevee.taa_samples = 1;
scene_eval->eevee.gi_irradiance_smoothing = 0.0f;
@@ -980,7 +980,7 @@ static void eevee_lightbake_copy_irradiance(EEVEE_LightBake *lbake, LightCache *
{
DRW_TEXTURE_FREE_SAFE(lbake->grid_prev);
- /* Copy texture by reading back and reuploading it. */
+ /* Copy texture by reading back and re-uploading it. */
float *tex = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_FLOAT, 0);
lbake->grid_prev = DRW_texture_create_2d_array(lbake->irr_size[0],
lbake->irr_size[1],
@@ -1330,7 +1330,7 @@ void EEVEE_lightbake_update(void *custom_data)
EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
Scene *scene_orig = lbake->scene;
- /* If a new lightcache was created, free the old one and reference the new. */
+ /* If a new light-cache was created, free the old one and reference the new. */
if (lbake->lcache && scene_orig->eevee.light_cache_data != lbake->lcache) {
if (scene_orig->eevee.light_cache_data != NULL) {
EEVEE_lightcache_free(scene_orig->eevee.light_cache_data);
@@ -1353,7 +1353,7 @@ static bool lightbake_do_sample(EEVEE_LightBake *lbake,
Depsgraph *depsgraph = lbake->depsgraph;
- /* TODO: make DRW manager instanciable (and only lock on drawing) */
+ /* TODO: make DRW manager instantiable (and only lock on drawing) */
eevee_lightbake_context_enable(lbake);
DRW_custom_pipeline(&draw_engine_eevee_type, depsgraph, render_callback, lbake);
lbake->done += 1;
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 3671bea9ac0..395d4dc790d 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -704,11 +704,11 @@ static void lightbake_planar_ensure_view(EEVEE_PlanarReflection *eplanar,
static void eevee_lightprobes_extract_from_cache(EEVEE_LightProbesInfo *pinfo, LightCache *lcache)
{
/* copy the entire cache for now (up to MAX_PROBE) */
- /* TODO Frutum cull to only add visible probes. */
+ /* TODO: frustum cull to only add visible probes. */
memcpy(pinfo->probe_data,
lcache->cube_data,
sizeof(EEVEE_LightProbe) * max_ii(1, min_ii(lcache->cube_len, MAX_PROBE)));
- /* TODO compute the max number of grid based on sample count. */
+ /* TODO: compute the max number of grid based on sample count. */
memcpy(pinfo->grid_data,
lcache->grid_data,
sizeof(EEVEE_LightGrid) * max_ii(1, min_ii(lcache->grid_len, MAX_GRID)));
@@ -1041,7 +1041,7 @@ void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata,
pinfo->layer = probe_idx * 6;
pinfo->roughness = i / (float)maxlevel;
pinfo->roughness *= pinfo->roughness; /* Disney Roughness */
- pinfo->roughness *= pinfo->roughness; /* Distribute Roughness accros lod more evenly */
+ pinfo->roughness *= pinfo->roughness; /* Distribute Roughness across lod more evenly. */
CLAMP(pinfo->roughness, 1e-8f, 0.99999f); /* Avoid artifacts */
#if 1 /* Variable Sample count and bias (fast) */
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index 628941f68a2..a9998b33b7e 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -344,7 +344,7 @@ void EEVEE_lookdev_draw(EEVEE_Data *vedata)
DRW_view_set_active(effects->lookdev_view);
- /* Find the right framebuffers to render to. */
+ /* Find the right frame-buffers to render to. */
GPUFrameBuffer *fb = (effects->target_buffer == fbl->effect_color_fb) ? fbl->main_fb :
fbl->effect_fb;
diff --git a/source/blender/draw/engines/eevee/eevee_lut_gen.c b/source/blender/draw/engines/eevee/eevee_lut_gen.c
index b74cb6c7687..18645fea5e0 100644
--- a/source/blender/draw/engines/eevee/eevee_lut_gen.c
+++ b/source/blender/draw/engines/eevee/eevee_lut_gen.c
@@ -22,7 +22,7 @@
* EEVEE LUT generation:
*
* Routine to generate the LUT used by eevee stored in eevee_lut.h
- * Theses functions are not to be used in the final executable.
+ * These functions are not to be used in the final executable.
*/
#include "DRW_render.h"
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 273521b0b28..5f2821730f1 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -234,7 +234,7 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
}
{
- /* Update noise Framebuffer. */
+ /* Update noise Frame-buffer. */
GPU_framebuffer_ensure_config(
&fbl->update_noise_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(e_data.util_tex, 2)});
@@ -415,7 +415,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
/* Renderpass accumulation. */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ADD_FULL;
- /* Create an instance of each of theses passes and link them together. */
+ /* Create an instance of each of these passes and link them together. */
DRWPass *passes[] = {
psl->material_ps,
psl->material_cull_ps,
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index 8dcab579603..0a79d9466e9 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -476,7 +476,7 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata)
if (vbo) {
/* Use the vbo to perform the copy on the GPU. */
GPU_vertbuf_use(vbo);
- /* Perform a copy to avoid loosing it after RE_engine_frame_set(). */
+ /* Perform a copy to avoid losing it after RE_engine_frame_set(). */
mb_geom->vbo[mb_step] = vbo = GPU_vertbuf_duplicate(vbo);
/* Find and replace "pos" attrib name. */
GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(vbo);
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index fd96a076c68..a3b581357e0 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -273,7 +273,7 @@ void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *
if (fbl->ao_accum_fb != NULL) {
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- /* Update the min_max/horizon buffers so the refracion materials appear in it. */
+ /* Update the min_max/horizon buffers so the refraction materials appear in it. */
EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1);
EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 9702db5fecc..e48f5f9dd32 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -518,7 +518,7 @@ typedef struct EEVEE_LightsInfo {
struct EEVEE_Shadow shadow_data[MAX_SHADOW];
struct EEVEE_ShadowCube shadow_cube_data[MAX_SHADOW_CUBE];
struct EEVEE_ShadowCascade shadow_cascade_data[MAX_SHADOW_CASCADE];
- /* Additionnal rendering info for cascade. */
+ /* Additional rendering info for cascade. */
struct EEVEE_ShadowCascadeRender shadow_cascade_render[MAX_SHADOW_CASCADE];
/* Back index in light_data. */
uchar shadow_cube_light_indices[MAX_SHADOW_CUBE];
@@ -716,7 +716,7 @@ typedef struct EEVEE_EffectsInfo {
CameraParams past_cam_params;
CameraParams current_cam_params;
char motion_blur_step; /* Which step we are evaluating. */
- int motion_blur_max; /* Maximum distance in pixels a motion blured pixel can cover. */
+ int motion_blur_max; /* Maximum distance in pixels a motion-blurred pixel can cover. */
float motion_blur_near_far[2]; /* Camera near/far clip distances (positive). */
bool cam_params_init;
/* TODO(fclem): Only used in render mode for now.
@@ -766,7 +766,7 @@ typedef struct EEVEE_EffectsInfo {
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. */
- struct GPUFrameBuffer *final_fb; /* Framebuffer with final_tx as attachment. */
+ struct GPUFrameBuffer *final_fb; /* Frame-buffer with final_tx as attachment. */
} EEVEE_EffectsInfo;
/* ***************** COMMON DATA **************** */
@@ -1431,7 +1431,7 @@ static const float texcomat[4][4] = {
{0.5f, 0.5f, 0.5f, 1.0f},
};
-/* Cubemap Matrices */
+/* Cube-map Matrices */
static const float cubefacemat[6][4][4] = {
/* Pos X */
{{0.0f, 0.0f, -1.0f, 0.0f},
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index bb974688404..72b12f6daeb 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -556,7 +556,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
DRW_render_instance_buffer_finish();
/* Need to be called after DRW_render_instance_buffer_finish() */
- /* Also we weed to have a correct fbo bound for DRW_hair_update */
+ /* Also we weed to have a correct FBO bound for DRW_hair_update */
GPU_framebuffer_bind(fbl->main_fb);
DRW_hair_update();
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index 52160248d75..9dec551e4b9 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -449,8 +449,8 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
(stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) :
stl->g_data->render_passes;
- bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) > 0;
- bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 &&
+ bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) != 0;
+ bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) != 0 &&
DRW_state_is_opengl_render();
UNUSED_VARS(needs_color_transfer);
diff --git a/source/blender/draw/engines/eevee/eevee_sampling.c b/source/blender/draw/engines/eevee/eevee_sampling.c
index 253dae79902..aa11f072fa5 100644
--- a/source/blender/draw/engines/eevee/eevee_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_sampling.c
@@ -69,11 +69,11 @@ void EEVEE_sample_rectangle(int sample_ofs,
BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point);
- /* Decorelate AA and shadow samples. (see T68594) */
+ /* De-correlate AA and shadow samples. (see T68594) */
ht_point[0] = fmod(ht_point[0] * 1151.0, 1.0);
ht_point[1] = fmod(ht_point[1] * 1069.0, 1.0);
- /* Change ditribution center to be 0,0 */
+ /* Change distribution center to be 0,0 */
ht_point[0] = (ht_point[0] > 0.5f) ? ht_point[0] - 1.0f : ht_point[0];
ht_point[1] = (ht_point[1] > 0.5f) ? ht_point[1] - 1.0f : ht_point[1];
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index ed7d53b51af..1465c9dd84c 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -106,7 +106,7 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
GPU_framebuffer_texture_attach(fbl->main_fb, effects->ssr_specrough_input, 2, 0);
- /* Raytracing output */
+ /* Ray-tracing output. */
effects->ssr_hit_output = DRW_texture_pool_query_2d(
tracing_res[0], tracing_res[1], GPU_RG16I, &draw_engine_eevee_type);
effects->ssr_pdf_output = DRW_texture_pool_query_2d(
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index 7a277c18f01..82b2395cc6e 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -85,7 +85,7 @@ static struct {
struct GPUShader *lookdev_background;
struct GPUShader *update_noise_sh;
- /* Downsample Depth */
+ /* Down-sample Depth */
struct GPUShader *minz_downlevel_sh;
struct GPUShader *maxz_downlevel_sh;
struct GPUShader *minz_downdepth_sh;
@@ -96,7 +96,7 @@ static struct {
struct GPUShader *minz_copydepth_sh;
struct GPUShader *maxz_copydepth_sh;
- /* Simple Downsample */
+ /* Simple Down-sample */
struct GPUShader *downsample_sh;
struct GPUShader *downsample_cube_sh;
@@ -258,7 +258,7 @@ static void eevee_shader_library_ensure(void)
{
if (e_data.lib == NULL) {
e_data.lib = DRW_shader_library_create();
- /* NOTE: Theses needs to be ordered by dependencies. */
+ /* NOTE: These need to be ordered by dependencies. */
DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
@@ -438,7 +438,7 @@ GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void)
}
/* -------------------------------------------------------------------- */
-/** \name Downsampling
+/** \name Down-sampling
* \{ */
GPUShader *EEVEE_shaders_effect_downsample_sh_get(void)
diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c
index fa5afd60235..e29830defff 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows.c
@@ -141,7 +141,7 @@ void EEVEE_shadows_caster_register(EEVEE_ViewLayerData *sldata, Object *ob)
}
if (ob->base_flag & BASE_FROM_DUPLI) {
- /* Duplis will always refresh the shadowmaps as if they were deleted each frame. */
+ /* Duplis will always refresh the shadow-maps as if they were deleted each frame. */
/* TODO(fclem): fix this. */
update = true;
}
@@ -259,7 +259,7 @@ void EEVEE_shadows_update(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
BoundSphere *bsphere = linfo->shadow_bounds;
/* Search for deleted shadow casters or if shcaster WAS in shadow radius. */
for (int i = 0; i < backbuffer->count; i++) {
- /* If the shadowcaster has been deleted or updated. */
+ /* If the shadow-caster has been deleted or updated. */
if (BLI_BITMAP_TEST(backbuffer->update, i)) {
for (int j = 0; j < linfo->cube_len; j++) {
if (!BLI_BITMAP_TEST(&linfo->sh_cube_update[0], j)) {
@@ -273,7 +273,7 @@ void EEVEE_shadows_update(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* Search for updates in current shadow casters. */
bbox = frontbuffer->bbox;
for (int i = 0; i < frontbuffer->count; i++) {
- /* If the shadowcaster has been updated. */
+ /* If the shadow-caster has been updated. */
if (BLI_BITMAP_TEST(frontbuffer->update, i)) {
for (int j = 0; j < linfo->cube_len; j++) {
if (!BLI_BITMAP_TEST(&linfo->sh_cube_update[0], j)) {
diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
index 246bc18b71a..6cb4b39fafa 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
@@ -330,7 +330,7 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
DRW_debug_sphere(center, csm_render->radius[c], dbg_col);
#endif
- /* Project into lightspace */
+ /* Project into light-space. */
mul_m4_v3(viewmat, center);
/* Snap projection center to nearest texel to cancel shimmering. */
@@ -376,7 +376,7 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
#endif
}
- /* Bias is in clipspace, divide by range. */
+ /* Bias is in clip-space, divide by range. */
shdw_data->bias = csm_render->original_bias * 0.05f / fabsf(sh_far - sh_near);
shdw_data->near = sh_near;
shdw_data->far = sh_far;
diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cube.c b/source/blender/draw/engines/eevee/eevee_shadows_cube.c
index 19b86476c29..89caa0dd193 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows_cube.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows_cube.c
@@ -142,7 +142,7 @@ static void eevee_ensure_cube_views(
float winmat[4][4];
float side = near;
- /* TODO shadowcube array. */
+ /* TODO: shadow-cube array. */
if (true) {
/* This half texel offset is used to ensure correct filtering between faces. */
/* FIXME: This exhibit float precision issue with lower cube_res.
diff --git a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
index 312d9f63ce0..0aa54715460 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
@@ -60,7 +60,7 @@ vec2 sample_weights(float center_depth,
float sample_motion_length,
float offset_length)
{
- /* Clasify foreground/background. */
+ /* Classify foreground/background. */
vec2 depth_weight = depth_compare(center_depth, sample_depth);
/* Weight if sample is overlapping or under the center pixel. */
vec2 spread_weight = spread_compare(center_motion_length, sample_motion_length, offset_length);
@@ -211,16 +211,16 @@ void main()
float w = 1.0 / (50.0 * float(KERNEL) * 4.0);
accum_bg += center_color * w;
w_accum.x += w;
- /* Note: In Jimenez's presentation, they used center sample.
- * We use background color as it contains more informations for foreground
+ /* NOTE: In Jimenez's presentation, they used center sample.
+ * We use background color as it contains more information for foreground
* elements that have not enough weights.
- * Yield beter blur in complex motion. */
+ * Yield better blur in complex motion. */
center_color = accum_bg / w_accum.x;
#endif
/* Merge background. */
accum += accum_bg;
w_accum.y += w_accum.x;
- /* Balance accumulation for failled samples.
+ /* Balance accumulation for failed samples.
* We replace the missing foreground by the background. */
float blend_fac = saturate(1.0 - w_accum.y / w_accum.z);
fragColor = (accum / w_accum.z) + center_color * blend_fac;
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 5f14f590128..aebd1c3aef3 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -238,7 +238,7 @@ vec3 raycast(int index,
#endif
}
- /* Discard backface hits. Only do this if the ray traveled enough to avoid loosing intricate
+ /* Discard backface hits. Only do this if the ray traveled enough to avoid losing intricate
* contact reflections. This is only used for SSReflections. */
if (discard_backface && prev_delta < 0.0 && curr_time > 4.1) {
hit = false;
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index 1b331052a06..adb21540afb 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -108,7 +108,7 @@ static void external_engine_init(void *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
ARegion *region = draw_ctx->region;
- /* Depth prepass */
+ /* Depth pre-pass. */
if (!e_data.depth_sh) {
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[GPU_SHADER_CFG_DEFAULT];
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index f2472699300..33b91efc848 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -365,7 +365,7 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
if (gpl->blend_mode == eGplBlendMode_HardLight) {
- /* We cannot do custom blending on MultiTarget framebuffers.
+ /* We cannot do custom blending on Multi-Target frame-buffers.
* Workaround by doing 2 passes. */
grp = DRW_shgroup_create(sh, tgp_layer->blend_ps);
DRW_shgroup_state_disable(grp, DRW_STATE_BLEND_MUL);
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 153dcfb6ea7..e738b0d063c 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -214,6 +214,7 @@ void GPENCIL_cache_init(void *ved)
NULL :
false;
pd->do_onion = show_onion && !hide_overlay && !playing;
+ pd->playing = playing;
/* Save simplify flags (can change while drawing, so it's better to save). */
Scene *scene = draw_ctx->scene;
pd->simplify_fill = GPENCIL_SIMPLIFY_FILL(scene, playing);
@@ -241,6 +242,7 @@ void GPENCIL_cache_init(void *ved)
pd->simplify_fill = false;
pd->simplify_fx = false;
pd->fade_layer_opacity = -1.0f;
+ pd->playing = false;
}
{
@@ -279,7 +281,7 @@ void GPENCIL_cache_init(void *ved)
});
}
else {
- /* Free uneeded buffers. */
+ /* Free unneeded buffers. */
GPU_FRAMEBUFFER_FREE_SAFE(fbl->snapshot_fb);
DRW_TEXTURE_FREE_SAFE(txl->snapshot_depth_tx);
DRW_TEXTURE_FREE_SAFE(txl->snapshot_color_tx);
@@ -331,7 +333,7 @@ void GPENCIL_cache_init(void *ved)
pd->dof_params[0] = -focus_dist * pd->dof_params[1];
}
else {
- /* Disable DoF blur scalling. */
+ /* Disable DoF blur scaling. */
pd->camera = NULL;
}
}
@@ -344,7 +346,7 @@ typedef struct gpIterPopulateData {
GPENCIL_PrivateData *pd;
GPENCIL_MaterialPool *matpool;
DRWShadingGroup *grp;
- /* Last material UBO bound. Used to avoid uneeded buffer binding. */
+ /* Last material UBO bound. Used to avoid unneeded buffer binding. */
GPUUniformBuf *ubo_mat;
GPUUniformBuf *ubo_lights;
/* Last texture bound. */
@@ -383,7 +385,7 @@ static void gpencil_drawcall_flush(gpIterPopulateData *iter)
iter->vcount = 0;
}
-/* Group drawcalls that are consecutive and with the same type. Reduces GPU driver overhead. */
+/* 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)
{
@@ -397,7 +399,7 @@ static void gpencil_drawcall_add(
#endif
int last = iter->vfirst + iter->vcount;
- /* Interupt drawcall grouping if the sequence is not consecutive. */
+ /* Interrupt draw-call grouping if the sequence is not consecutive. */
if ((geom != iter->geom) || (v_first - last > 3)) {
gpencil_drawcall_flush(iter);
}
@@ -617,6 +619,15 @@ void GPENCIL_cache_populate(void *ved, Object *ob)
/* Special case for rendering onion skin. */
bGPdata *gpd = (bGPdata *)ob->data;
bool do_onion = (!pd->is_render) ? pd->do_onion : (gpd->onion_flag & GP_ONION_GHOST_ALWAYS);
+ gpd->runtime.playing = (short)pd->playing;
+
+ /* When render in background the active frame could not be properly set due thread priority
+ * better set again. This is not required in viewport. */
+ if (txl->render_depth_tx) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ gpl->actframe = BKE_gpencil_layer_frame_get(gpl, pd->cfra, GP_GETFRAME_USE_PREV);
+ }
+ }
/* When render in background the active frame could not be properly set due thread priority
* better set again. This is not required in viewport. */
@@ -675,7 +686,7 @@ void GPENCIL_cache_finish(void *ved)
/* Sort object by decreasing Z to avoid most of alpha ordering issues. */
gpencil_object_cache_sort(pd);
- /* Create framebuffers only if needed. */
+ /* Create frame-buffers only if needed. */
if (pd->tobjects.first) {
eGPUTextureFormat format = pd->use_signed_fb ? GPU_RGBA16F : GPU_R11F_G11F_B10F;
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index d0bd56b42dd..5ceb909bc88 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -110,7 +110,7 @@ BLI_STATIC_ASSERT_ALIGN(gpLight, 16)
typedef struct GPENCIL_MaterialPool {
/* Linklist. */
struct GPENCIL_MaterialPool *next;
- /* GPU representatin of materials. */
+ /* GPU representation of materials. */
gpMaterial mat_data[GP_MATERIAL_BUFFER_LEN];
/* Matching ubo. */
struct GPUUniformBuf *ubo;
@@ -122,7 +122,7 @@ typedef struct GPENCIL_MaterialPool {
} GPENCIL_MaterialPool;
typedef struct GPENCIL_LightPool {
- /* GPU representatin of materials. */
+ /* GPU representation of materials. */
gpLight light_data[GPENCIL_LIGHT_BUFFER_LEN];
/* Matching ubo. */
struct GPUUniformBuf *ubo;
@@ -151,7 +151,7 @@ typedef struct GPENCIL_tVfx {
/** Linklist */
struct GPENCIL_tVfx *next;
DRWPass *vfx_ps;
- /* Framebuffer reference since it may not be allocated yet. */
+ /* Frame-buffer reference since it may not be allocated yet. */
GPUFrameBuffer **target_fb;
} GPENCIL_tVfx;
@@ -342,6 +342,8 @@ typedef struct GPENCIL_PrivateData {
/* Display onion skinning */
bool do_onion;
+ /* Playing animation */
+ bool playing;
/* simplify settings */
bool simplify_fill;
bool simplify_fx;
@@ -350,7 +352,7 @@ typedef struct GPENCIL_PrivateData {
bool use_lighting;
/* Use physical lights or just ambient lighting. */
bool use_lights;
- /* Do we need additional framebuffers? */
+ /* Do we need additional frame-buffers? */
bool use_layer_fb;
bool use_object_fb;
bool use_mask_fb;
diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c
index 9ac9a4dc078..b597a786e86 100644
--- a/source/blender/draw/engines/gpencil/gpencil_render.c
+++ b/source/blender/draw/engines/gpencil/gpencil_render.c
@@ -47,7 +47,7 @@ void GPENCIL_render_init(GPENCIL_Data *vedata,
const float *viewport_size = DRW_viewport_size_get();
const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
- /* Set the pers & view matrix. */
+ /* Set the perspective & view matrix. */
float winmat[4][4], viewmat[4][4], viewinv[4][4];
struct Object *camera = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index cb65fbd6ae7..0b66141e51a 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -235,7 +235,7 @@ static void gpencil_vfx_rim(RimShaderFxData *fx, Object *ob, gpIterVfxData *iter
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
if (fx->mode == eShaderFxRimMode_Overlay) {
- /* We cannot do custom blending on MultiTarget framebuffers.
+ /* We cannot do custom blending on multi-target frame-buffers.
* Workaround by doing 2 passes. */
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_state_disable(grp, DRW_STATE_BLEND_MUL);
@@ -363,7 +363,7 @@ static void gpencil_vfx_shadow(ShadowShaderFxData *fx, Object *ob, gpIterVfxData
copy_v2_v2(wave_ofs, wave_dir);
SWAP(float, wave_ofs[0], wave_ofs[1]);
wave_ofs[1] *= -1.0f;
- /* Keep world space scalling and aspect ratio. */
+ /* Keep world space scaling and aspect ratio. */
mul_v2_fl(wave_dir, 1.0f / (max_ff(1e-8f, fx->period) * distance_factor));
mul_v2_v2(wave_dir, vp_size);
mul_v2_fl(wave_ofs, fx->amplitude * distance_factor);
@@ -397,7 +397,7 @@ static void gpencil_vfx_shadow(ShadowShaderFxData *fx, Object *ob, gpIterVfxData
unit_m4(uv_mat);
zero_v2(wave_ofs);
- /* We reseted the uv_mat so we need to accound for the rotation in the */
+ /* We reset the uv_mat so we need to account for the rotation in the */
copy_v2_fl2(tmp, 0.0f, blur_size[1]);
rotate_v2_v2fl(blur_dir, tmp, -fx->rotation);
mul_v2_v2(blur_dir, vp_size_inv);
@@ -515,7 +515,7 @@ static void gpencil_vfx_wave(WaveShaderFxData *fx, Object *ob, gpIterVfxData *it
copy_v2_v2(wave_ofs, wave_dir);
SWAP(float, wave_ofs[0], wave_ofs[1]);
wave_ofs[1] *= -1.0f;
- /* Keep world space scalling and aspect ratio. */
+ /* Keep world space scaling and aspect ratio. */
mul_v2_fl(wave_dir, 1.0f / (max_ff(1e-8f, fx->period) * distance_factor));
mul_v2_v2(wave_dir, vp_size);
mul_v2_fl(wave_ofs, fx->amplitude * distance_factor);
@@ -647,7 +647,7 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObjec
DRW_shgroup_uniform_int_copy(grp, "isFirstPass", true);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
- /* We cannot do custom blending on MultiTarget framebuffers.
+ /* We cannot do custom blending on multi-target frame-buffers.
* Workaround by doing 2 passes. */
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_state_disable(grp, DRW_STATE_BLEND_MUL);
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 189ed91cbb4..3065d553dce 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -393,7 +393,7 @@ void stroke_vertex()
is_squares = false;
}
- /* Enpoints, we discard the vertices. */
+ /* Endpoints, we discard the vertices. */
if (ma1.x == -1 || (!is_dot && ma2.x == -1)) {
discard_vert();
return;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl
index 503248558ad..aedc8668387 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl
@@ -274,7 +274,7 @@ uniform bool isFirstPass;
vec2 compute_uvs(float x)
{
vec2 uv = uvcoordsvar.xy;
- /* Tranform UV (loc, rot, scale) */
+ /* Transform UV (loc, rot, scale) */
uv = uv.x * uvRotX + uv.y * uvRotY + uvOffset;
uv += blurDir * x;
/* Wave deform. */
diff --git a/source/blender/draw/engines/image/image_shader.c b/source/blender/draw/engines/image/image_shader.c
index 7dc428de2ee..691c0d7029a 100644
--- a/source/blender/draw/engines/image/image_shader.c
+++ b/source/blender/draw/engines/image/image_shader.c
@@ -49,7 +49,7 @@ void IMAGE_shader_library_ensure(void)
{
if (e_data.lib == NULL) {
e_data.lib = DRW_shader_library_create();
- /* NOTE: Theses needs to be ordered by dependencies. */
+ /* NOTE: These need to be ordered by dependencies. */
DRW_SHADER_LIB_ADD(e_data.lib, common_colormanagement_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_globals_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.c
index 229f9c5a88f..b263254696c 100644
--- a/source/blender/draw/engines/overlay/overlay_antialiasing.c
+++ b/source/blender/draw/engines/overlay/overlay_antialiasing.c
@@ -80,7 +80,7 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
bool need_wire_expansion = (G_draw.block.sizePixel > 1.0f);
pd->antialiasing.enabled = need_wire_expansion ||
- ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) > 0);
+ ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) != 0);
GPUTexture *color_tex = NULL;
GPUTexture *line_tex = NULL;
@@ -93,7 +93,7 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
line_tex = txl->overlay_line_tx;
}
else {
- /* Just a copy of the defaults framebuffers. */
+ /* Just a copy of the defaults frame-buffers. */
color_tex = dtxl->color_overlay;
}
@@ -127,7 +127,7 @@ void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
if (pd->antialiasing.enabled) {
/* `antialiasing.enabled` is also enabled for wire expansion. Check here if
* anti aliasing is needed. */
- const bool do_smooth_lines = (U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) > 0;
+ const bool do_smooth_lines = (U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) != 0;
DRW_PASS_CREATE(psl->antialiasing_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL);
diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c
index cbd2589f20f..7042d095b56 100644
--- a/source/blender/draw/engines/overlay/overlay_armature.c
+++ b/source/blender/draw/engines/overlay/overlay_armature.c
@@ -1691,13 +1691,13 @@ static void draw_bone_degrees_of_freedom(ArmatureDrawContext *ctx, bPoseChannel
unit_m4(posetrans);
translate_m4(posetrans, pchan->pose_mat[3][0], pchan->pose_mat[3][1], pchan->pose_mat[3][2]);
- /* in parent-bone pose space... */
+ /* In parent-bone pose space... */
if (pchan->parent) {
copy_m4_m4(tmp, pchan->parent->pose_mat);
zero_v3(tmp[3]);
mul_m4_m4m4(posetrans, posetrans, tmp);
}
- /* ... but own restspace */
+ /* ... but own rest-space. */
mul_m4_m4m3(posetrans, posetrans, pchan->bone->bone_mat);
float scale = pchan->bone->length * pchan->size[1];
diff --git a/source/blender/draw/engines/overlay/overlay_edit_mesh.c b/source/blender/draw/engines/overlay/overlay_edit_mesh.c
index 38e171cb5e2..40a9dbe01c0 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_mesh.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_mesh.c
@@ -344,7 +344,7 @@ void OVERLAY_edit_mesh_draw(OVERLAY_Data *vedata)
if (pd->edit_mesh.do_zbufclip) {
DRW_draw_pass(psl->edit_mesh_depth_ps[IN_FRONT]);
- /* render facefill */
+ /* Render face-fill. */
DRW_view_set_active(pd->view_edit_faces);
DRW_draw_pass(psl->edit_mesh_faces_ps[NOT_IN_FRONT]);
diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.c b/source/blender/draw/engines/overlay/overlay_edit_uv.c
index 22433905b75..97dcf934c11 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_uv.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_uv.c
@@ -161,7 +161,7 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
pd->edit_uv.do_tiled_image_border_overlay = is_image_type && is_tiled_image;
pd->edit_uv.dash_length = 4.0f * UI_DPI_FAC;
pd->edit_uv.line_style = edit_uv_line_style_from_space_image(sima);
- pd->edit_uv.do_smooth_wire = ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) > 0);
+ 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;
diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c
index 39f17581e0d..00429a19cf4 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.c
@@ -642,10 +642,10 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
} instdata;
copy_m4_m4(instdata.mat, ob->obmat);
- /* FIXME / TODO: clipend has no meaning nowadays.
- * In EEVEE, Only clipsta is used shadowmaping.
+ /* 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.
- * For now, always use the custom distance as clipend. */
+ * For now, always use the custom distance as clip_end. */
instdata.clip_end = la->att_dist;
instdata.clip_sta = la->clipsta;
@@ -1176,7 +1176,7 @@ void OVERLAY_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
invert_v3(scale);
for (int i = 0; i < 4; i++) {
mul_v3_v3(vec[i], scale);
- /* Project to z=-1 plane. Makes positionning / scaling easier. (see shader) */
+ /* Project to z=-1 plane. Makes positioning / scaling easier. (see shader) */
mul_v2_fl(vec[i], 1.0f / fabsf(vec[i][2]));
}
diff --git a/source/blender/draw/engines/overlay/overlay_gpencil.c b/source/blender/draw/engines/overlay/overlay_gpencil.c
index 7f9290a6c3a..19af3ae7e5d 100644
--- a/source/blender/draw/engines/overlay/overlay_gpencil.c
+++ b/source/blender/draw/engines/overlay/overlay_gpencil.c
@@ -258,6 +258,16 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
copy_m4_m4(mat, ob->obmat);
+ /* Rotate and scale except align to cursor. */
+ bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
+ if (gpl != NULL) {
+ if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR) {
+ float matrot[3][3];
+ copy_m3_m4(matrot, gpl->layer_mat);
+ mul_m4_m4m3(mat, mat, matrot);
+ }
+ }
+
float viewinv[4][4];
/* Set the grid in the selected axis */
switch (ts->gp_sculpt.lock_axis) {
@@ -294,6 +304,11 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
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});
+ /* Apply layer loc transform, except cursor mode. */
+ if ((gpl != NULL) && (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ add_v3_v3(mat[3], gpl->layer_mat[3]);
+ }
+
const int gridlines = (gpd->grid.lines <= 0) ? 1 : gpd->grid.lines;
int line_ct = gridlines * 4 + 2;
diff --git a/source/blender/draw/engines/overlay/overlay_metaball.c b/source/blender/draw/engines/overlay/overlay_metaball.c
index f973c1eda8a..46076a7c88b 100644
--- a/source/blender/draw/engines/overlay/overlay_metaball.c
+++ b/source/blender/draw/engines/overlay/overlay_metaball.c
@@ -63,7 +63,7 @@ static void metaball_instance_data_set(
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);
- /* WATCH: Reminder, alpha is wiresize. */
+ /* WATCH: Reminder, alpha is wire-size. */
OVERLAY_bone_instance_data_set_color(data, color);
}
diff --git a/source/blender/draw/engines/overlay/overlay_particle.c b/source/blender/draw/engines/overlay/overlay_particle.c
index fa95bad4d86..71064e7ff47 100644
--- a/source/blender/draw/engines/overlay/overlay_particle.c
+++ b/source/blender/draw/engines/overlay/overlay_particle.c
@@ -185,7 +185,7 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* TODO(fclem): Here would be a good place for preemptive culling. */
- /* fclem: Is color even usefull in our modern context? */
+ /* NOTE(fclem): Is color even useful in our modern context? */
Material *ma = BKE_object_material_get(ob, part->omat);
float color[4] = {0.6f, 0.6f, 0.6f, part->draw_size};
if (ma != NULL) {
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index 88f4e28c039..6b07547bf96 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -238,7 +238,7 @@ void OVERLAY_shader_library_ensure(void)
{
if (e_data.lib == NULL) {
e_data.lib = DRW_shader_library_create();
- /* NOTE: Theses needs to be ordered by dependencies. */
+ /* NOTE: These need to be ordered by dependencies. */
DRW_SHADER_LIB_ADD(e_data.lib, common_globals_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_overlay_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_colormanagement_lib);
diff --git a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl b/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
index 2989e07691f..f24aee56bb2 100644
--- a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
@@ -146,7 +146,7 @@ void main()
vec4 lines = vec4(neightbor_line0.z, neightbor_line1.z, neightbor_line2.z, neightbor_line3.z);
/* Count number of line neighbors. */
float blend = dot(vec4(0.25), step(0.001, lines));
- /* Only do blend if there is more than 2 neighbor. This avoid loosing too much AA. */
+ /* Only do blend if there are more than 2 neighbors. This avoids losing too much AA. */
blend = clamp(blend * 2.0 - 1.0, 0.0, 1.0);
fragColor = mix(fragColor, fragColor / fragColor.a, blend);
}
diff --git a/source/blender/draw/engines/overlay/shaders/extra_vert.glsl b/source/blender/draw/engines/overlay/shaders/extra_vert.glsl
index 89bc0bcf522..74854dc0f8d 100644
--- a/source/blender/draw/engines/overlay/shaders/extra_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/extra_vert.glsl
@@ -222,7 +222,7 @@ void main()
edgePos = edgeStart = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
#ifdef SELECT_EDGES
- /* HACK: to avoid loosing sub pixel object in selections, we add a bit of randomness to the
+ /* 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 += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
diff --git a/source/blender/draw/engines/overlay/shaders/extra_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/extra_wire_vert.glsl
index 8a80441b5d9..91f45329018 100644
--- a/source/blender/draw/engines/overlay/shaders/extra_wire_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/extra_wire_vert.glsl
@@ -18,7 +18,7 @@ void main()
gl_Position = point_world_to_ndc(world_pos);
#ifdef SELECT_EDGES
- /* HACK: to avoid loosing sub pixel object in selections, we add a bit of randomness to the
+ /* 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 += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
diff --git a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
index c80d8f99628..c083fdacbbe 100644
--- a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
@@ -169,7 +169,7 @@ void main()
}
#ifdef SELECT_EDGES
- /* HACK: to avoid loosing sub pixel object in selections, we add a bit of randomness to the
+ /* 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 += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
#endif
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 eaa553a10de..9bd49bb84f8 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -288,7 +288,7 @@ void main()
ls_ray_dir -= ls_ray_ori;
- /* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */
+ /* TODO: Align rays to volume center so that it mimics old behavior of slicing the volume. */
float dist = line_unit_box_intersect_dist(ls_ray_ori, ls_ray_dir);
if (dist > 0.0) {
diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
index 20c30d9ce68..feb48b2623d 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
@@ -75,7 +75,7 @@ static void workbench_taa_jitter_init_order(float (*table)[2], int num)
swap_v2_v2(table[0], table[closest_index]);
}
- /* sort list based on furtest distance with previous */
+ /* Sort list based on farthest distance with previous. */
for (int i = 0; i < num - 2; i++) {
float f_squared_dist = 0.0;
int f_index = i;
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c
index 73cd501190f..a00453fe125 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c
@@ -104,7 +104,7 @@ static void workbench_dof_setup_samples(struct GPUUniformBuf **ubo,
square_to_circle(x, y, &r, &T);
samp[2] = r;
- /* Bokeh shape parametrisation */
+ /* Bokeh shape parameterization. */
if (bokeh_sides > 1.0f) {
float denom = T - (2.0 * M_PI / bokeh_sides) *
floorf((bokeh_sides * T + M_PI) / (2.0 * M_PI));
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 6aa794bda51..6e9118bfe46 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -76,7 +76,7 @@ void workbench_material_ubo_data(WORKBENCH_PrivateData *wpd,
alpha *= mat->a;
copy_v3_v3(data->base_color, &mat->r);
metallic = mat->metallic;
- roughness = sqrtf(mat->roughness); /* Remap to disney roughness. */
+ roughness = sqrtf(mat->roughness); /* Remap to Disney roughness. */
}
else {
copy_v3_fl(data->base_color, 0.8f);
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index d157c260fbd..522aae7f542 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -225,7 +225,7 @@ BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_Material, 16)
typedef struct WORKBENCH_Prepass {
/** Hash storing shading group for each Material or GPUTexture to reduce state changes. */
struct GHash *material_hash;
- /** First common (non-vcol and non-image colored) shading group to created subgroups. */
+ /** First common (non-vertex-color and non-image-colored) shading group to created subgroups. */
struct DRWShadingGroup *common_shgrp;
/** First Vertex Color shading group to created subgroups. */
struct DRWShadingGroup *vcol_shgrp;
@@ -384,7 +384,7 @@ typedef struct WORKBENCH_ViewLayerData {
struct GPUUniformBuf *cavity_sample_ubo;
/** Blue noise texture used to randomize the sampling of some effects.*/
struct GPUTexture *cavity_jitter_tx;
- /** Materials ubos allocated in a memblock for easy bookeeping. */
+ /** Materials UBO's allocated in a memblock for easy bookkeeping. */
struct BLI_memblock *material_ubo;
struct BLI_memblock *material_ubo_data;
/** Number of samples for which cavity_sample_ubo is valid. */
diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c
index 1c612404c95..ad610a6a885 100644
--- a/source/blender/draw/engines/workbench/workbench_shader.c
+++ b/source/blender/draw/engines/workbench/workbench_shader.c
@@ -120,7 +120,7 @@ void workbench_shader_library_ensure(void)
{
if (e_data.lib == NULL) {
e_data.lib = DRW_shader_library_create();
- /* NOTE: Theses needs to be ordered by dependencies. */
+ /* NOTE: These need to be ordered by dependencies. */
DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
diff --git a/source/blender/draw/engines/workbench/workbench_shadow.c b/source/blender/draw/engines/workbench/workbench_shadow.c
index 881c186e3e5..99d945c311e 100644
--- a/source/blender/draw/engines/workbench/workbench_shadow.c
+++ b/source/blender/draw/engines/workbench/workbench_shadow.c
@@ -157,7 +157,7 @@ void workbench_shadow_cache_init(WORKBENCH_Data *data)
DRWState state = DRW_STATE_DEPTH_LESS | DRW_STATE_STENCIL_ALWAYS;
#endif
- /* TODO(fclem): Merge into one pass with subpasses. */
+ /* TODO(fclem): Merge into one pass with sub-passes. */
DRW_PASS_CREATE(psl->shadow_ps[0], state | depth_pass_state);
DRW_PASS_CREATE(psl->shadow_ps[1], state | depth_fail_state);
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 4a43107c612..2545cfa65dc 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -93,7 +93,7 @@ typedef char DRWViewportEmptyList;
#define DRW_VIEWPORT_LIST_SIZE(list) \
(sizeof(list) == sizeof(DRWViewportEmptyList) ? 0 : ((sizeof(list)) / sizeof(void *)))
-/* Unused members must be either pass list or 'char *' when not usd. */
+/* Unused members must be either pass list or 'char *' when not used. */
#define DRW_VIEWPORT_DATA_SIZE(ty) \
{ \
DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->fbl)), DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->txl)), \
@@ -327,14 +327,14 @@ typedef enum {
/** Culling test */
DRW_STATE_CULL_BACK = (1 << 7),
DRW_STATE_CULL_FRONT = (1 << 8),
- /** Stencil test . These options are mutal exclusive and packed into 2 bits*/
+ /** Stencil test . These options are mutually exclusive and packed into 2 bits. */
DRW_STATE_STENCIL_ALWAYS = (1 << 9),
DRW_STATE_STENCIL_EQUAL = (2 << 9),
DRW_STATE_STENCIL_NEQUAL = (3 << 9),
/** Blend state. These options are mutual exclusive and packed into 4 bits */
DRW_STATE_BLEND_ADD = (1 << 11),
- /** Same as additive but let alpha accumulate without premult. */
+ /** Same as additive but let alpha accumulate without pre-multiply. */
DRW_STATE_BLEND_ADD_FULL = (2 << 11),
/** Standard alpha blending. */
DRW_STATE_BLEND_ALPHA = (3 << 11),
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 5333f59bf38..fcd626eb92b 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -1325,7 +1325,7 @@ GPUBatch *DRW_cache_field_vortex_get(void)
#undef SPIRAL_RESOL
}
-/* Screenaligned circle. */
+/* Screen-aligned circle. */
GPUBatch *DRW_cache_field_curve_get(void)
{
#define CIRCLE_RESOL 32
@@ -1414,7 +1414,7 @@ GPUBatch *DRW_cache_field_cone_limit_get(void)
#undef CIRCLE_RESOL
}
-/* Screenaligned dashed circle */
+/* Screen-aligned dashed circle */
GPUBatch *DRW_cache_field_sphere_limit_get(void)
{
#define CIRCLE_RESOL 32
@@ -3385,7 +3385,7 @@ GPUBatch *DRW_cache_particles_get_prim(int type)
int v = 0;
int flag = VCLASS_EMPTY_AXES;
- /* Set minimum to 0.001f so we can easilly normalize to get the color. */
+ /* Set minimum to 0.001f so we can easily normalize to get the color. */
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0f, 0.0001f, 0.0f}, flag});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0f, 2.0f, 0.0f}, flag});
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0001f, 0.0f, 0.0f}, flag});
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 9fd7ffd4692..c15c246992d 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -239,7 +239,7 @@ typedef struct DRWVolumeGrid {
float texture_to_object[4][4];
float object_to_texture[4][4];
- /* Transfrom from bounds to texture space. */
+ /* Transform from bounds to texture space. */
float object_to_bounds[4][4];
float bounds_to_texture[4][4];
} DRWVolumeGrid;
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 9e2ac26f9f0..d9fbb01789f 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -907,7 +907,7 @@ static void extract_tris_finish(const MeshRenderData *mr,
if (mr->use_final_mesh && cache->final.tris_per_mat) {
MeshBufferCache *mbc = &cache->final;
for (int i = 0; i < mr->mat_len; i++) {
- /* Theses IBOs have not been queried yet but we create them just in case they are needed
+ /* These IBOs have not been queried yet but we create them just in case they are needed
* later since they are not tracked by mesh_buffer_cache_create_requested(). */
if (mbc->tris_per_mat[i] == NULL) {
mbc->tris_per_mat[i] = GPU_indexbuf_calloc();
@@ -1380,7 +1380,7 @@ static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
}
}
else {
- /* Set theses unselected loop only if this edge has no other selected loop. */
+ /* Set these unselected loop only if this edge has no other selected loop. */
if (!BLI_BITMAP_TEST(data->select_map, e_index)) {
GPU_indexbuf_set_line_verts(&data->elb, e_index, ml_index, ml_index_other);
}
@@ -5230,7 +5230,7 @@ static void *extract_skin_roots_init(const MeshRenderData *mr,
}
}
- /* It's really unlikely that all verts will be roots. Resize to avoid loosing VRAM. */
+ /* It's really unlikely that all verts will be roots. Resize to avoid losing VRAM. */
GPU_vertbuf_data_len_set(vbo, root_len);
return NULL;
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index 72f3e7b0fa8..d606f70db9e 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -774,7 +774,7 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(ListBase *lb,
}
}
-/* Edge detection/adjecency */
+/* Edge detection/adjacency. */
#define NO_EDGE INT_MAX
static void set_edge_adjacency_lines_indices(
EdgeHash *eh, GPUIndexBufBuilder *elb, bool *r_is_manifold, uint v1, uint v2, uint v3)
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c
index e1523db36c7..8feacf8b026 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c
@@ -800,20 +800,20 @@ static void gpencil_edit_curve_stroke_iter_cb(bGPDlayer *gpl,
};
/* First segment. */
- copy_v3_v3(vert_ptr->pos, bezt->vec[0]);
+ mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[0]);
vert_ptr->data = vflag[0];
vert_ptr++;
- copy_v3_v3(vert_ptr->pos, bezt->vec[1]);
+ mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[1]);
vert_ptr->data = vflag[1];
vert_ptr++;
/* Second segment. */
- copy_v3_v3(vert_ptr->pos, bezt->vec[1]);
+ mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[1]);
vert_ptr->data = vflag[1];
vert_ptr++;
- copy_v3_v3(vert_ptr->pos, bezt->vec[2]);
+ mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[2]);
vert_ptr->data = vflag[2];
vert_ptr++;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_hair.c b/source/blender/draw/intern/draw_cache_impl_hair.c
index 327a92a997e..fd28ac00186 100644
--- a/source/blender/draw/intern/draw_cache_impl_hair.c
+++ b/source/blender/draw/intern/draw_cache_impl_hair.c
@@ -318,7 +318,7 @@ bool hair_ensure_procedural_data(Object *object,
HairBatchCache *cache = hair_batch_cache_get(hair);
*r_hair_cache = &cache->hair;
- const int steps = 2; /* TODO: don't hardcode? */
+ const int steps = 2; /* TODO: don't hard-code? */
(*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv);
/* Refreshed on combing and simulation. */
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 3f014a01680..1a1caa2943a 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -405,7 +405,7 @@ static void drw_mesh_weight_state_extract(Object *ob,
&wstate->defgroup_sel_count);
}
}
- /* With only one selected bone Multipaint reverts to regular mode. */
+ /* With only one selected bone Multi-paint reverts to regular mode. */
else {
wstate->defgroup_sel_count = 0;
MEM_SAFE_FREE(wstate->defgroup_sel);
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index 5029e71cac8..fef8ba4b606 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -161,7 +161,7 @@ void DRW_globals_update(void)
/* Grid */
UI_GetThemeColorShade4fv(TH_GRID, 10, gb->colorGrid);
- /* emphasise division lines lighter instead of darker, if background is darker than grid */
+ /* Emphasize division lines lighter instead of darker, if background is darker than grid. */
UI_GetThemeColorShade4fv(
TH_GRID,
(gb->colorGrid[0] + gb->colorGrid[1] + gb->colorGrid[2] + 0.12f >
@@ -333,7 +333,7 @@ int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color
theme_id = TH_EMPTY;
break;
case OB_LIGHTPROBE:
- /* TODO add lightprobe color */
+ /* TODO: add light-probe color. */
theme_id = TH_EMPTY;
break;
default:
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 86f1b0e0ebb..bca227a24e2 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -320,7 +320,7 @@ void DRW_hair_update(void)
max_size = max_ii(max_size, pr_call->vert_len);
}
- /* Create target Texture / Framebuffer */
+ /* Create target Texture / Frame-buffer */
/* Don't use max size as it can be really heavy and fail.
* Do chunks of maximum 2048 * 2048 hair points. */
int width = 2048;
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index bc41eab9e22..fd31a11b0a8 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1570,13 +1570,13 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
drw_engines_data_validate();
- /* Update ubos */
+ /* Update UBO's */
DRW_globals_update();
drw_debug_init();
DRW_hair_init();
- /* No framebuffer allowed before drawing. */
+ /* No frame-buffer allowed before drawing. */
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
/* Init engines */
@@ -1642,7 +1642,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
DRW_draw_callbacks_post_scene();
if (WM_draw_region_get_bound_viewport(region)) {
- /* Don't unbind the framebuffer yet in this case and let
+ /* Don't unbind the frame-buffer yet in this case and let
* GPU_viewport_unbind do it, so that we can still do further
* drawing of action zones on top. */
}
@@ -1706,7 +1706,7 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
if (draw_background) {
/* HACK(fclem): In this case we need to make sure the final alpha is 1.
* We use the blend mode to ensure that. A better way to fix that would
- * be to do that in the colormanagmeent shader. */
+ * be to do that in the color-management shader. */
GPU_offscreen_bind(ofs, false);
GPU_clear_color(0.0f, 0.0f, 0.0f, 1.0f);
/* Premult Alpha over black background. */
@@ -2088,12 +2088,12 @@ void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph,
drw_engines_enable_editors();
drw_engines_data_validate();
- /* Update ubos */
+ /* Update UBO's */
DRW_globals_update();
drw_debug_init();
- /* No framebuffer allowed before drawing. */
+ /* No frame-buffer allowed before drawing. */
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
GPU_framebuffer_bind(DST.default_framebuffer);
GPU_framebuffer_clear_depth_stencil(DST.default_framebuffer, 1.0f, 0xFF);
@@ -2191,7 +2191,7 @@ void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph,
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
if (WM_draw_region_get_bound_viewport(region)) {
- /* Don't unbind the framebuffer yet in this case and let
+ /* Don't unbind the frame-buffer yet in this case and let
* GPU_viewport_unbind do it, so that we can still do further
* drawing of action zones on top. */
}
@@ -2373,7 +2373,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
drw_context_state_init();
drw_viewport_var_init();
- /* Update ubos */
+ /* Update UBO's */
DRW_globals_update();
/* Init engines */
@@ -2445,7 +2445,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
DRW_render_instance_buffer_finish();
}
- /* Setup framebuffer */
+ /* Setup frame-buffer. */
draw_select_framebuffer_depth_only_setup(viewport_size);
GPU_framebuffer_bind(g_select_buffer.framebuffer_depth_only);
GPU_framebuffer_clear_depth(g_select_buffer.framebuffer_depth_only, 1.0f);
@@ -2489,11 +2489,11 @@ 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_imp(struct Depsgraph *depsgraph,
- ARegion *region,
- View3D *v3d,
- GPUViewport *viewport,
- const bool use_opengl_context)
+static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph,
+ ARegion *region,
+ View3D *v3d,
+ GPUViewport *viewport,
+ const bool use_opengl_context)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
@@ -2521,7 +2521,7 @@ static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph,
drw_task_graph_init();
drw_engines_data_validate();
- /* Setup framebuffer */
+ /* Setup frame-buffer. */
DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(
DST.viewport);
GPU_framebuffer_bind(fbl->depth_only_fb);
@@ -2531,7 +2531,7 @@ static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph,
drw_context_state_init();
drw_viewport_var_init();
- /* Update ubos */
+ /* Update UBO's */
DRW_globals_update();
/* Init engines */
@@ -2587,7 +2587,7 @@ static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph,
drw_state_ensure_not_reused(&DST);
#endif
- /* Changin context */
+ /* Changing context. */
if (use_opengl_context) {
DRW_opengl_context_disable();
}
@@ -2616,7 +2616,7 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
}
}
- drw_draw_depth_loop_imp(depsgraph, region, v3d, viewport, use_opengl_context);
+ drw_draw_depth_loop_impl(depsgraph, region, v3d, viewport, use_opengl_context);
}
/**
@@ -2632,7 +2632,7 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
use_drw_engine(&draw_engine_gpencil_type);
- drw_draw_depth_loop_imp(depsgraph, region, v3d, viewport, true);
+ drw_draw_depth_loop_impl(depsgraph, region, v3d, viewport, true);
}
void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const rcti *rect)
@@ -2671,7 +2671,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
DST.viewport = viewport;
drw_viewport_var_init();
- /* Update ubos */
+ /* Update UBO's */
DRW_globals_update();
/* Init Select Engine */
@@ -2728,7 +2728,7 @@ void DRW_draw_depth_object(
GPU_matrix_set(rv3d->viewmat);
GPU_matrix_mul(object->obmat);
- /* Setup framebuffer */
+ /* Setup frame-buffer. */
DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
GPU_framebuffer_bind(fbl->depth_only_fb);
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 3ab60bc3c96..f540ff09032 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -266,14 +266,14 @@ typedef union DRWCommand {
DRWCommandClear clear;
} DRWCommand;
-/* Used for agregating calls into GPUVertBufs. */
+/** Used for aggregating calls into #GPUVertBuf's. */
struct DRWCallBuffer {
GPUVertBuf *buf;
GPUVertBuf *buf_select;
int count;
};
-/* Used by DRWUniform.type */
+/** Used by #DRWUniform.type */
typedef enum {
DRW_UNIFORM_INT = 0,
DRW_UNIFORM_INT_COPY,
@@ -324,8 +324,8 @@ struct DRWUniform {
/* DRW_UNIFORM_BLOCK_OBATTRS */
struct GPUUniformAttrList *uniform_attrs;
};
- int location; /* Uniform location or binding point for textures and ubos. */
- uint8_t type; /* DRWUniformType */
+ int location; /* Uniform location or binding point for textures and UBO's. */
+ uint8_t type; /* #DRWUniformType */
uint8_t length; /* Length of vector types. */
uint8_t arraysize; /* Array size of scalar/vector types. */
};
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 57b3373932e..6bdc5305fed 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -978,7 +978,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 depsgrah eval. */
+ /* PBVH should always exist for non-empty meshes, created by depsgraph eval. */
PBVH *pbvh = (scd->ob->sculpt) ? scd->ob->sculpt->pbvh : NULL;
if (!pbvh) {
return;
@@ -1601,10 +1601,10 @@ static void draw_frustum_bound_sphere_calc(const BoundBox *bbox,
/* Detect which of the corner of the far clipping plane is the farthest to the origin */
float nfar[4]; /* most extreme far point in NDC space */
- float farxy[2]; /* farpoint projection onto the near plane */
+ float farxy[2]; /* far-point projection onto the near plane */
float farpoint[3] = {0.0f}; /* most extreme far point in camera coordinate */
float nearpoint[3]; /* most extreme near point in camera coordinate */
- float farcenter[3] = {0.0f}; /* center of far cliping plane in camera coordinate */
+ float farcenter[3] = {0.0f}; /* center of far clipping plane in camera coordinate */
float F = -1.0f, N; /* square distance of far and near point to origin */
float f, n; /* distance of far and near point to z axis. f is always > 0 but n can be < 0 */
float e, s; /* far and near clipping distance (<0) */
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 5f7aa28c3c9..4c8fcb0e016 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -272,7 +272,7 @@ static void drw_stencil_state_set(uint write_mask, uint reference, uint compare_
GPU_stencil_compare_mask_set(compare_mask);
}
-/* Reset state to not interfer with other UI drawcall */
+/* Reset state to not interfere with other UI draw-call. */
void DRW_state_reset_ex(DRWState state)
{
DST.state = ~state;
@@ -344,7 +344,7 @@ void DRW_state_reset(void)
/* Should stay constant during the whole rendering. */
GPU_point_size(5);
GPU_line_smooth(false);
- /* Bypass U.pixelsize factor by using a factor of 0.0f. Will be clamped to 1.0f. */
+ /* Bypass #U.pixelsize factor by using a factor of 0.0f. Will be clamped to 1.0f. */
GPU_line_width(0.0f);
}
@@ -855,7 +855,7 @@ static void draw_call_batching_do(DRWShadingGroup *shgroup,
DRWCommandsState *state,
DRWCommandDraw *call)
{
- /* If any condition requires to interupt the merging. */
+ /* If any condition requires to interrupt the merging. */
bool neg_scale = DRW_handle_negative_scale_get(&call->handle);
int chunk = DRW_handle_chunk_get(&call->handle);
int id = DRW_handle_id_get(&call->handle);
diff --git a/source/blender/draw/intern/draw_manager_texture.c b/source/blender/draw/intern/draw_manager_texture.c
index 8b948e62cf3..e9432f370b8 100644
--- a/source/blender/draw/intern/draw_manager_texture.c
+++ b/source/blender/draw/intern/draw_manager_texture.c
@@ -26,7 +26,7 @@
/* Maybe gpu_texture.c is a better place for this. */
static bool drw_texture_format_supports_framebuffer(eGPUTextureFormat format)
{
- /* Some formats do not work with framebuffers. */
+ /* Some formats do not work with frame-buffers. */
switch (format) {
/* Only add formats that are COMPATIBLE with FB.
* Generally they are multiple of 16bit. */
diff --git a/source/blender/draw/intern/shaders/common_fxaa_lib.glsl b/source/blender/draw/intern/shaders/common_fxaa_lib.glsl
index a87b4558227..0ecfc397e95 100644
--- a/source/blender/draw/intern/shaders/common_fxaa_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_fxaa_lib.glsl
@@ -1,7 +1,7 @@
/* ---------------------------------------------------------------------------------
* File: es3-kepler\FXAA/FXAA3_11.h
* SDK Version: v3.00
- * Email: gameworks@nvidia.com
+ * Email: <gameworks@nvidia.com>
* Site: http://developer.nvidia.com/
*
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
diff --git a/source/blender/draw/intern/shaders/common_smaa_lib.glsl b/source/blender/draw/intern/shaders/common_smaa_lib.glsl
index 78a62c6ae7d..36ffb4d8b32 100644
--- a/source/blender/draw/intern/shaders/common_smaa_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_smaa_lib.glsl
@@ -118,7 +118,7 @@
* half-rate linear filtering on GCN.
*
* If SMAA is applied to 64-bit color buffers, switching to point filtering
- * when accesing them will increase the performance. Search for
+ * when accessing them will increase the performance. Search for
* 'SMAASamplePoint' to see which textures may benefit from point
* filtering, and where (which is basically the color input in the edge
* detection and resolve passes).
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 05cbb3ef48f..24bb58535a5 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -133,7 +133,16 @@ static void acf_generic_root_backdrop(bAnimContext *ac,
UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT :
(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
UI_draw_roundbox_3fv_alpha(
- true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ &(const rctf){
+ .xmin = offset,
+ .xmax = v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ true,
+ 8,
+ color,
+ 1.0f);
}
/* get backdrop color for data expanders under top-level Scene/Object */
@@ -421,7 +430,7 @@ static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac,
case ACHANNEL_SETTING_MUTE:
return ((ac) && (ac->spacetype == SPACE_NLA));
- /* select is ok for most "ds*" channels (e.g. dsmat) */
+ /* Select is ok for most `ds*` channels (e.g. `dsmat`) */
case ACHANNEL_SETTING_SELECT:
return true;
@@ -464,7 +473,16 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
*/
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
UI_draw_roundbox_3fv_alpha(
- true, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ &(const rctf){
+ .xmin = 0,
+ .xmax = v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ .ymin = yminc - 2,
+ .ymax = ymaxc,
+ },
+ true,
+ 8,
+ color,
+ 1.0f);
}
/* name for summary entries */
@@ -875,7 +893,16 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
UI_draw_roundbox_3fv_alpha(
- true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ &(const rctf){
+ .xmin = offset,
+ .xmax = v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ true,
+ 8,
+ color,
+ 1.0f);
}
/* name for group entries */
@@ -1149,7 +1176,16 @@ static void acf_nla_controls_backdrop(bAnimContext *ac,
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
UI_draw_roundbox_3fv_alpha(
- true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5, color, 1.0f);
+ &(const rctf){
+ .xmin = offset,
+ .xmax = v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ true,
+ 5,
+ color,
+ 1.0f);
}
/* name for nla controls expander entries */
@@ -3936,13 +3972,16 @@ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float y
/* draw slightly shifted up vertically to look like it has more separation from other channels,
* but we then need to slightly shorten it so that it doesn't look like it overlaps
*/
- UI_draw_roundbox_4fv(true,
- offset,
- yminc + NLACHANNEL_SKIP,
- (float)v2d->cur.xmax,
- ymaxc + NLACHANNEL_SKIP - 1,
- 8,
- color);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = offset,
+ .xmax = (float)v2d->cur.xmax,
+ .ymin = yminc + NLACHANNEL_SKIP,
+ .ymax = ymaxc + NLACHANNEL_SKIP - 1,
+ },
+ true,
+ 8,
+ color);
}
/* name for nla action entries */
@@ -4710,7 +4749,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
(float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, adt, &anim_eval_context, false);
+ &nla_cache, &id_ptr, adt, &anim_eval_context);
/* get current frame and apply NLA-mapping to it (if applicable) */
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
@@ -4766,7 +4805,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
(float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, key->adt, &anim_eval_context, false);
+ &nla_cache, &id_ptr, key->adt, &anim_eval_context);
/* get current frame and apply NLA-mapping to it (if applicable) */
const float remapped_frame = BKE_nla_tweakedit_remap(
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index a6e96a4d919..109cf79c786 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -393,7 +393,11 @@ static void anim_channels_select_set(bAnimContext *ac,
FCurve *fcu = (FCurve *)ale->data;
ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED);
- fcu->flag &= ~FCURVE_ACTIVE;
+ if ((fcu->flag & FCURVE_SELECTED) == 0) {
+ /* Only erase the ACTIVE flag when deselecting. This ensures that "select all curves"
+ * retains the currently active curve. */
+ fcu->flag &= ~FCURVE_ACTIVE;
+ }
break;
}
case ANIMTYPE_SHAPEKEY: {
@@ -1197,7 +1201,7 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn
rearrange_animchannel_islands(
&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
- /* Add back non-local NLA tracks at the begining of the animation data's list. */
+ /* Add back non-local NLA tracks at the beginning of the animation data's list. */
if (!BLI_listbase_is_empty(&extracted_nonlocal_nla_tracks)) {
BLI_assert(is_liboverride);
((NlaTrack *)extracted_nonlocal_nla_tracks.last)->next = adt->nla_tracks.first;
@@ -1732,7 +1736,7 @@ static int animchannels_group_exec(bContext *C, wmOperator *op)
/* free temp data */
ANIM_animdata_freelist(&anim_data);
- /* updatss */
+ /* Updates. */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index f2022194ed5..a03f19d0111 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -2403,6 +2403,13 @@ static void animfilter_modifier_idpoin_cb(void *afm_ptr,
}
break;
}
+ case ID_NT: {
+ bNodeTree *node_tree = (bNodeTree *)id;
+ if (!(afm->ads->filterflag & ADS_FILTER_NONTREE)) {
+ afm->items += animdata_filter_ds_nodetree(
+ afm->ac, &afm->tmp_data, afm->ads, owner_id, node_tree, afm->filter_mode);
+ }
+ }
/* TODO: images? */
default:
diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
index 088ac9dbcba..aac2465d43a 100644
--- a/source/blender/editors/animation/anim_motion_paths.c
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -331,7 +331,7 @@ static void motionpath_calculate_update_range(MPathTarget *mpt,
int fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, &fcu_keys, current_frame);
int fcu_efra = motionpath_get_next_next_keyframe(mpt, &fcu_keys, current_frame);
- /* Extend range furher, since accelleration compensation propagates even further away. */
+ /* Extend range further, since acceleration compensation propagates even further away. */
if (fcu->auto_smoothing != FCURVE_SMOOTH_NONE) {
fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, &fcu_keys, fcu_sfra);
fcu_efra = motionpath_get_next_next_keyframe(mpt, &fcu_keys, fcu_efra);
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index a5514f6517e..72d9bff545a 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -29,12 +29,10 @@
#include "BLI_math_base.h"
#include "BLI_utildefines.h"
-#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
-#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -50,10 +48,8 @@
#include "ED_screen.h"
#include "ED_sequencer.h"
#include "ED_time_scrub_ui.h"
-#include "ED_util.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "SEQ_sequencer.h"
#include "SEQ_time.h"
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index b2a9d6ac9b7..43d5efe9ea9 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -33,7 +33,6 @@
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
-#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "BKE_anim_data.h"
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 542a6d45db7..b9ef69cf8bd 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -258,6 +258,10 @@ static DLRBT_Node *nalloc_ak_gpframe(void *data)
/* count keyframes in this column */
ak->totkey = 1;
+ /* Set as visible block. */
+ ak->totblock = 1;
+ ak->block.sel = ak->sel;
+ ak->block.flag |= ACTKEYBLOCK_FLAG_GPENCIL;
return (DLRBT_Node *)ak;
}
@@ -689,6 +693,7 @@ static void draw_keylist(View2D *v2d,
{
const float icon_sz = U.widget_unit * 0.5f * yscale_fac;
const float half_icon_sz = 0.5f * icon_sz;
+ const float quarter_icon_sz = 0.25f * icon_sz;
const float smaller_sz = 0.35f * icon_sz;
const float ipo_sz = 0.1f * icon_sz;
@@ -724,6 +729,7 @@ static void draw_keylist(View2D *v2d,
ipo_color_mix[3] *= 0.5f;
uint block_len = 0;
+ uint gpencil_len = 0;
LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
if (actkeyblock_get_valid_hold(ab)) {
block_len++;
@@ -731,50 +737,72 @@ static void draw_keylist(View2D *v2d,
if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
block_len++;
}
+ if ((ab->next != NULL) && (ab->block.flag & ACTKEYBLOCK_FLAG_GPENCIL)) {
+ gpencil_len++;
+ }
}
- if (block_len > 0) {
+ if ((block_len > 0) || (gpencil_len > 0)) {
GPUVertFormat *format = immVertexFormat();
uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GPU_PRIM_TRIS, 6 * block_len);
- LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
- int valid_hold = actkeyblock_get_valid_hold(ab);
- if (valid_hold != 0) {
- if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
- /* draw "moving hold" long-keyframe block - slightly smaller */
- immRectf_fast_with_color(pos_id,
- color_id,
- ab->cfra,
- ypos - smaller_sz,
- ab->next->cfra,
- ypos + smaller_sz,
- (ab->block.sel) ? sel_mhcol : unsel_mhcol);
+ /* Normal Dopesheet. */
+ if (block_len > 0) {
+ immBegin(GPU_PRIM_TRIS, 6 * block_len);
+ LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
+ int valid_hold = actkeyblock_get_valid_hold(ab);
+ if (valid_hold != 0) {
+ if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
+ /* draw "moving hold" long-keyframe block - slightly smaller */
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - smaller_sz,
+ ab->next->cfra,
+ ypos + smaller_sz,
+ (ab->block.sel) ? sel_mhcol : unsel_mhcol);
+ }
+ else {
+ /* draw standard long-keyframe block */
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - half_icon_sz,
+ ab->next->cfra,
+ ypos + half_icon_sz,
+ (ab->block.sel) ? sel_color : unsel_color);
+ }
}
- else {
- /* draw standard long-keyframe block */
- immRectf_fast_with_color(pos_id,
- color_id,
- ab->cfra,
- ypos - half_icon_sz,
- ab->next->cfra,
- ypos + half_icon_sz,
- (ab->block.sel) ? sel_color : unsel_color);
+ if (show_ipo && actkeyblock_is_valid(ab) &&
+ (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
+ /* draw an interpolation line */
+ immRectf_fast_with_color(
+ pos_id,
+ color_id,
+ ab->cfra,
+ ypos - ipo_sz,
+ ab->next->cfra,
+ ypos + ipo_sz,
+ (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
}
}
- if (show_ipo && actkeyblock_is_valid(ab) &&
- (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
- /* draw an interpolation line */
- immRectf_fast_with_color(
- pos_id,
- color_id,
- ab->cfra,
- ypos - ipo_sz,
- ab->next->cfra,
- ypos + ipo_sz,
- (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
+ }
+ /* Grease Pencil Dopesheet. */
+ else {
+ immBegin(GPU_PRIM_TRIS, 6 * gpencil_len);
+ LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
+ if (ab->next == NULL) {
+ continue;
+ }
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - quarter_icon_sz,
+ ab->next->cfra,
+ ypos + quarter_icon_sz,
+ (ab->block.sel) ? sel_mhcol : unsel_mhcol);
}
}
immEnd();
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 6ed9803dbd3..72e65272f13 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -39,13 +39,11 @@
#include "BKE_action.h"
#include "BKE_curve.h"
-#include "BKE_deform.h"
#include "BKE_fcurve.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index e8146ca960a..0d1633ab3a2 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -614,7 +614,7 @@ int insert_vert_fcurve(
return -1;
}
- /* set handletype and interpolation */
+ /* Set handle-type and interpolation. */
if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) {
BezTriple *bezt = (fcu->bezt + a);
@@ -1384,7 +1384,7 @@ static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval
if (adt && adt->action == act) {
/* Get NLA context for value remapping. */
*r_nla_context = BKE_animsys_get_nla_keyframing_context(
- nla_cache, id_ptr, adt, anim_eval_context, false);
+ nla_cache, id_ptr, adt, anim_eval_context);
/* Apply NLA-mapping to frame. */
const float remapped_frame = BKE_nla_tweakedit_remap(
diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c
index 98b4d93fbf1..034378399b9 100644
--- a/source/blender/editors/animation/time_scrub_ui.c
+++ b/source/blender/editors/animation/time_scrub_ui.c
@@ -124,23 +124,22 @@ static void draw_current_frame(const Scene *scene,
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_3fv_alpha(true,
- frame_x - box_width / 2 + U.pixelsize / 2,
- scrub_region_rect->ymin + box_padding,
- frame_x + box_width / 2 + U.pixelsize / 2,
- scrub_region_rect->ymax - box_padding,
- 4 * UI_DPI_FAC,
- bg_color,
- 1.0f);
-
- UI_GetThemeColorShade4fv(TH_CFRAME, 5, bg_color);
- UI_draw_roundbox_aa(false,
- frame_x - box_width / 2 + U.pixelsize / 2,
- scrub_region_rect->ymin + box_padding,
- frame_x + box_width / 2 + U.pixelsize / 2,
- scrub_region_rect->ymax - box_padding,
- 4 * UI_DPI_FAC,
- bg_color);
+ float outline_color[4];
+ UI_GetThemeColorShade4fv(TH_CFRAME, 5, outline_color);
+
+ UI_draw_roundbox_4fv_ex(
+ &(const rctf){
+ .xmin = frame_x - box_width / 2 + U.pixelsize / 2,
+ .xmax = frame_x + box_width / 2 + U.pixelsize / 2,
+ .ymin = scrub_region_rect->ymin + box_padding,
+ .ymax = scrub_region_rect->ymax - box_padding,
+ },
+ bg_color,
+ NULL,
+ 1.0f,
+ outline_color,
+ U.pixelsize,
+ 4 * UI_DPI_FAC);
uchar text_color[4];
UI_GetThemeColor4ubv(TH_HEADER_TEXT_HI, text_color);
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index a0b8bf862d7..68fff1091af 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -122,9 +122,6 @@ EditBone *ED_armature_ebone_add_primitive(Object *obedit_arm, float length, bool
return bone;
}
-/* previously addvert_armature */
-/* the ctrl-click method */
-
/**
* Note this is already ported to multi-objects as it is.
* Since only the active bone is extruded even for single objects,
@@ -306,8 +303,7 @@ static EditBone *get_named_editbone(ListBase *edbo, const char *name)
return NULL;
}
-/* Call this before doing any duplications
- * */
+/* Call this before doing any duplications. */
void preEditBoneDuplicate(ListBase *editbones)
{
/* clear temp */
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index da1b29307b1..a0face26bae 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -28,8 +28,6 @@
#include "ED_armature.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
-#include "ED_transform.h"
#include "armature_intern.h"
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 6951ed6f305..f86ec545712 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -30,7 +30,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_string_utils.h"
@@ -50,8 +49,6 @@
#include "ED_armature.h"
#include "ED_mesh.h"
-#include "eigen_capi.h"
-
#include "armature_intern.h"
#include "meshlaplacian.h"
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index fba88e78162..3d1d8d0d1f1 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -699,11 +699,11 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
BKE_armature_bonelist_free(&arm->bonebase, true);
arm->act_bone = NULL;
- /* remove zero sized bones, this gives unstable restposes */
+ /* Remove zero sized bones, this gives unstable rest-poses. */
for (eBone = arm->edbo->first; eBone; eBone = neBone) {
float len_sq = len_squared_v3v3(eBone->head, eBone->tail);
neBone = eBone->next;
- /* TODO(sergey): How to ensure this is a constexpr? */
+ /* TODO(sergey): How to ensure this is a `constexpr`? */
if (len_sq <= square_f(0.000001f)) { /* FLT_EPSILON is too large? */
EditBone *fBone;
diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.c
index c6d7d2eb869..337d1138b23 100644
--- a/source/blender/editors/armature/editarmature_undo.c
+++ b/source/blender/editors/armature/editarmature_undo.c
@@ -178,8 +178,11 @@ static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain,
return true;
}
-static void armature_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void armature_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
ArmatureUndoStep *us = (ArmatureUndoStep *)us_p;
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 3c0b6dacbf6..e362a2e2f40 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -422,7 +422,7 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr
}
}
-/* Raytracing for vertex to bone/vertex visibility */
+/* Ray-tracing for vertex to bone/vertex visibility. */
static void heat_ray_tree_create(LaplacianSystem *sys)
{
const MLoopTri *looptri = sys->heat.mlooptri;
@@ -497,7 +497,7 @@ static float heat_source_distance(LaplacianSystem *sys, int vertex, int source)
{
float closest[3], d[3], dist, cosine;
- /* compute euclidian distance */
+ /* compute Euclidean distance */
closest_to_line_segment_v3(
closest, sys->heat.verts[vertex], sys->heat.root[source], sys->heat.tip[source]);
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 91893af003f..78bce8679bb 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -149,7 +149,7 @@ bool ED_object_posemode_exit(bContext *C, Object *ob)
return ok;
}
-/* if a selected or active bone is protected, throw error (oonly if warn == 1) and return 1 */
+/* if a selected or active bone is protected, throw error (only if warn == 1) and return 1 */
/* only_selected == 1: the active bone is allowed to be protected */
#if 0 /* UNUSED 2.5 */
static bool pose_has_protected_selected(Object *ob, short warn)
diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c
index 55c9877e55f..38d15d8b880 100644
--- a/source/blender/editors/armature/pose_group.c
+++ b/source/blender/editors/armature/pose_group.c
@@ -423,7 +423,7 @@ static int group_sort_exec(bContext *C, wmOperator *UNUSED(op))
BLI_addtail(&pose->agroups, agrp_array[i].agrp);
}
- /* fix changed bone group indizes in bones */
+ /* Fix changed bone group indices in bones. */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (i = 0; i < agrp_count; i++) {
if (pchan->agrp_index == agrp_array[i].index) {
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 947e2dbf5aa..45f623f3a9d 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -1106,7 +1106,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
if (pchan) {
if (!any_bone_selected || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) {
if (autokey) {
- /* add datasource override for the PoseChannel, to be used later */
+ /* Add data-source override for the PoseChannel, to be used later. */
ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan);
/* clear any unkeyed tags */
@@ -1142,7 +1142,7 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
/* only recalc pose (and its dependencies) if pose has changed */
if (pld->redraw == PL_PREVIEW_REDRAWALL) {
- /* don't clear pose if firsttime */
+ /* Don't clear pose if first time. */
if ((pld->flag & PL_PREVIEW_FIRSTTIME) == 0) {
poselib_backup_restore(pld);
}
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 4b646bb26e2..d636f0d68af 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -689,7 +689,7 @@ static void pose_slide_rest_pose_apply(bContext *C, tPoseSlideOp *pso)
/* Not strictly a transform, but custom properties contribute
* to the pose produced in many rigs (e.g. the facial rigs used in Sintel). */
/* TODO Not implemented */
- // pose_slide_apply_props(pso, pfl, "[\""); /* dummy " for texteditor bugs */
+ // pose_slide_apply_props(pso, pfl, "[\"");
}
}
@@ -702,7 +702,7 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
{
tPChanFCurveLink *pfl;
- /* sanitise the frame ranges */
+ /* Sanitize the frame ranges. */
if (pso->prevFrame == pso->nextFrame) {
/* move out one step either side */
pso->prevFrame--;
@@ -765,7 +765,7 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_PROPS) && (pfl->oldprops)) {
/* Not strictly a transform, but custom properties contribute
* to the pose produced in many rigs (e.g. the facial rigs used in Sintel). */
- pose_slide_apply_props(pso, pfl, "[\""); /* dummy " for texteditor bugs */
+ pose_slide_apply_props(pso, pfl, "[\"");
}
}
@@ -1125,7 +1125,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_PRESS) {
switch (event->type) {
/* Transform Channel Limits */
- /* XXX: Replace these hardcoded hotkeys with a modalmap that can be customised */
+ /* XXX: Replace these hard-coded hotkeys with a modal-map that can be customized. */
case EVT_GKEY: /* Location */
{
pose_slide_toggle_channels_mode(op, pso, PS_TFM_LOC);
@@ -1183,7 +1183,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else {
- /* unhandled event - maybe it was some view manip? */
+ /* unhandled event - maybe it was some view manipulation? */
/* allow to pass through */
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
}
@@ -1246,15 +1246,15 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
{
PropertyRNA *prop;
- prop = RNA_def_float_percentage(ot->srna,
- "percentage",
- 0.5f,
- 0.0f,
- 1.0f,
- "Percentage",
- "Weighting factor for which keyframe is favored more",
- 0.0,
- 1.0);
+ prop = RNA_def_float_factor(ot->srna,
+ "factor",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Factor",
+ "Weighting factor for which keyframe is favored more",
+ 0.0,
+ 1.0);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_int(ot->srna,
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 3505aea3f40..722865cc942 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -225,7 +225,7 @@ static void applyarmature_process_selected_recursive(bArmature *arm,
ApplyArmature_ParentState new_pstate = {.bone = bone};
if (BLI_findptr(selected, pchan, offsetof(CollectionPointerLink, ptr.data))) {
- /* SELECTED BONE: Snap to final pose transform minus unapplied parent effects.
+ /* SELECTED BONE: Snap to final pose transform minus un-applied parent effects.
*
* I.e. bone position with accumulated parent effects but no local
* transformation will match the original final pose_mat.
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index 2a6dc9f406b..c75e9c9ef69 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -33,7 +33,6 @@
#include "BKE_action.h"
#include "BKE_anim_data.h"
-#include "BKE_armature.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_object.h"
@@ -312,7 +311,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks,
continue;
}
- /* add datasource override for the PoseChannel, to be used later */
+ /* Add data-source override for the PoseChannel, to be used later. */
ANIM_relative_keyingset_add_source(&dsources, &pfl->ob->id, &RNA_PoseBone, pchan);
/* clear any unkeyed tags */
diff --git a/source/blender/editors/asset/CMakeLists.txt b/source/blender/editors/asset/CMakeLists.txt
index 6cd94783251..8c5f91561b7 100644
--- a/source/blender/editors/asset/CMakeLists.txt
+++ b/source/blender/editors/asset/CMakeLists.txt
@@ -29,8 +29,8 @@ set(INC_SYS
)
set(SRC
- asset_edit.c
- asset_ops.c
+ asset_edit.cc
+ asset_ops.cc
)
set(LIB
diff --git a/source/blender/editors/asset/asset_edit.c b/source/blender/editors/asset/asset_edit.cc
index 3dca87d3a03..d20de4141cb 100644
--- a/source/blender/editors/asset/asset_edit.c
+++ b/source/blender/editors/asset/asset_edit.cc
@@ -20,11 +20,9 @@
#include "BKE_asset.h"
#include "BKE_context.h"
-#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "DNA_ID.h"
-#include "DNA_asset_types.h"
#include "UI_interface_icons.h"
@@ -45,7 +43,7 @@ bool ED_asset_mark_id(const bContext *C, ID *id)
id->asset_data = BKE_asset_metadata_create();
- UI_icon_render_id(C, NULL, id, ICON_SIZE_PREVIEW, true);
+ UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
return true;
}
@@ -65,5 +63,5 @@ bool ED_asset_clear_id(ID *id)
bool ED_asset_can_make_single_from_context(const bContext *C)
{
/* Context needs a "id" pointer to be set for #ASSET_OT_mark()/#ASSET_OT_clear() to use. */
- return CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data != NULL;
+ return CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data != nullptr;
}
diff --git a/source/blender/editors/asset/asset_ops.c b/source/blender/editors/asset/asset_ops.c
deleted file mode 100644
index 29c3174f051..00000000000
--- a/source/blender/editors/asset/asset_ops.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup edasset
- */
-
-#include <string.h>
-
-#include "BKE_asset.h"
-#include "BKE_context.h"
-#include "BKE_report.h"
-
-#include "BLI_listbase.h"
-#include "BLI_string_utils.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_asset_types.h"
-#include "DNA_userdef_types.h"
-
-#include "ED_asset.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-/* -------------------------------------------------------------------- */
-
-struct AssetMarkResultStats {
- int tot_created;
- int tot_already_asset;
- ID *last_id;
-};
-
-static bool asset_ops_poll(bContext *UNUSED(C))
-{
- return U.experimental.use_asset_browser;
-}
-
-/**
- * Return the IDs to operate on as list of #CollectionPointerLink links. Needs freeing.
- */
-static ListBase /* CollectionPointerLink */ asset_operation_get_ids_from_context(const bContext *C)
-{
- ListBase list = {0};
-
- PointerRNA idptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
-
- if (idptr.data) {
- CollectionPointerLink *ctx_link = MEM_callocN(sizeof(*ctx_link), __func__);
- ctx_link->ptr = idptr;
- BLI_addtail(&list, ctx_link);
- }
- else {
- CTX_data_selected_ids(C, &list);
- }
-
- return list;
-}
-
-static void asset_mark_for_idptr_list(const bContext *C,
- const ListBase /* CollectionPointerLink */ *ids,
- struct AssetMarkResultStats *r_stats)
-{
- memset(r_stats, 0, sizeof(*r_stats));
-
- LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, ids) {
- BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type));
-
- ID *id = ctx_id->ptr.data;
- if (id->asset_data) {
- r_stats->tot_already_asset++;
- continue;
- }
-
- if (ED_asset_mark_id(C, id)) {
- r_stats->last_id = id;
- r_stats->tot_created++;
- }
- }
-}
-
-static bool asset_mark_results_report(const struct AssetMarkResultStats *stats,
- ReportList *reports)
-{
- /* User feedback on failure. */
- if ((stats->tot_created < 1) && (stats->tot_already_asset > 0)) {
- BKE_report(reports,
- RPT_ERROR,
- "Selected data-blocks are already assets (or do not support use as assets)");
- return false;
- }
- if (stats->tot_created < 1) {
- BKE_report(reports,
- RPT_ERROR,
- "No data-blocks to create assets for found (or do not support use as assets)");
- return false;
- }
-
- /* User feedback on success. */
- if (stats->tot_created == 1) {
- /* If only one data-block: Give more useful message by printing asset name. */
- BKE_reportf(reports, RPT_INFO, "Data-block '%s' is now an asset", stats->last_id->name + 2);
- }
- else {
- BKE_reportf(reports, RPT_INFO, "%i data-blocks are now assets", stats->tot_created);
- }
-
- return true;
-}
-
-static int asset_mark_exec(bContext *C, wmOperator *op)
-{
- ListBase ids = asset_operation_get_ids_from_context(C);
-
- struct AssetMarkResultStats stats;
- asset_mark_for_idptr_list(C, &ids, &stats);
- BLI_freelistN(&ids);
-
- if (!asset_mark_results_report(&stats, op->reports)) {
- return OPERATOR_CANCELLED;
- }
-
- WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
- WM_main_add_notifier(NC_ASSET | NA_ADDED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-static void ASSET_OT_mark(wmOperatorType *ot)
-{
- ot->name = "Mark Asset";
- ot->description =
- "Enable easier reuse of selected data-blocks through the Asset Browser, with the help of "
- "customizable metadata (like previews, descriptions and tags)";
- ot->idname = "ASSET_OT_mark";
-
- ot->exec = asset_mark_exec;
- ot->poll = asset_ops_poll;
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/* -------------------------------------------------------------------- */
-
-struct AssetClearResultStats {
- int tot_removed;
- ID *last_id;
-};
-
-static void asset_clear_from_idptr_list(const ListBase /* CollectionPointerLink */ *ids,
- struct AssetClearResultStats *r_stats)
-{
- memset(r_stats, 0, sizeof(*r_stats));
-
- LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, ids) {
- BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type));
-
- ID *id = ctx_id->ptr.data;
- if (!id->asset_data) {
- continue;
- }
-
- if (ED_asset_clear_id(id)) {
- r_stats->tot_removed++;
- r_stats->last_id = id;
- }
- }
-}
-
-static bool asset_clear_result_report(const struct AssetClearResultStats *stats,
- ReportList *reports)
-
-{
- if (stats->tot_removed < 1) {
- BKE_report(reports, RPT_ERROR, "No asset data-blocks selected/focused");
- return false;
- }
-
- if (stats->tot_removed == 1) {
- /* If only one data-block: Give more useful message by printing asset name. */
- BKE_reportf(
- reports, RPT_INFO, "Data-block '%s' is no asset anymore", stats->last_id->name + 2);
- }
- else {
- BKE_reportf(reports, RPT_INFO, "%i data-blocks are no assets anymore", stats->tot_removed);
- }
-
- return true;
-}
-
-static int asset_clear_exec(bContext *C, wmOperator *op)
-{
- ListBase ids = asset_operation_get_ids_from_context(C);
-
- struct AssetClearResultStats stats;
- asset_clear_from_idptr_list(&ids, &stats);
- BLI_freelistN(&ids);
-
- if (!asset_clear_result_report(&stats, op->reports)) {
- return OPERATOR_CANCELLED;
- }
-
- WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
- WM_main_add_notifier(NC_ASSET | NA_REMOVED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-static void ASSET_OT_clear(wmOperatorType *ot)
-{
- ot->name = "Clear Asset";
- ot->description =
- "Delete all asset metadata and turn the selected asset data-blocks back into normal "
- "data-blocks";
- ot->idname = "ASSET_OT_clear";
-
- ot->exec = asset_clear_exec;
- ot->poll = asset_ops_poll;
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/* -------------------------------------------------------------------- */
-
-void ED_operatortypes_asset(void)
-{
- WM_operatortype_append(ASSET_OT_mark);
- WM_operatortype_append(ASSET_OT_clear);
-}
diff --git a/source/blender/editors/asset/asset_ops.cc b/source/blender/editors/asset/asset_ops.cc
new file mode 100644
index 00000000000..8ca1b488a1d
--- /dev/null
+++ b/source/blender/editors/asset/asset_ops.cc
@@ -0,0 +1,259 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edasset
+ */
+
+#include "BKE_context.h"
+#include "BKE_report.h"
+
+#include "BLI_vector.hh"
+
+#include "ED_asset.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* -------------------------------------------------------------------- */
+
+using PointerRNAVec = blender::Vector<PointerRNA>;
+
+static bool asset_operation_poll(bContext * /*C*/)
+{
+ return U.experimental.use_asset_browser;
+}
+
+/**
+ * Return the IDs to operate on as PointerRNA vector. Either a single one ("id" context member) or
+ * multiple ones ("selected_ids" context member).
+ */
+static PointerRNAVec asset_operation_get_ids_from_context(const bContext *C)
+{
+ PointerRNAVec ids;
+
+ PointerRNA idptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
+ if (idptr.data) {
+ /* Single ID. */
+ ids.append(idptr);
+ }
+ else {
+ ListBase list;
+ CTX_data_selected_ids(C, &list);
+ LISTBASE_FOREACH (CollectionPointerLink *, link, &list) {
+ ids.append(link->ptr);
+ }
+ BLI_freelistN(&list);
+ }
+
+ return ids;
+}
+
+/* -------------------------------------------------------------------- */
+
+class AssetMarkHelper {
+ public:
+ void operator()(const bContext &C, PointerRNAVec &ids);
+
+ void reportResults(ReportList &reports) const;
+ bool wasSuccessful() const;
+
+ private:
+ struct Stats {
+ int tot_created = 0;
+ int tot_already_asset = 0;
+ ID *last_id = nullptr;
+ };
+
+ Stats stats;
+};
+
+void AssetMarkHelper::operator()(const bContext &C, PointerRNAVec &ids)
+{
+ for (PointerRNA &ptr : ids) {
+ BLI_assert(RNA_struct_is_ID(ptr.type));
+
+ ID *id = static_cast<ID *>(ptr.data);
+ if (id->asset_data) {
+ stats.tot_already_asset++;
+ continue;
+ }
+
+ if (ED_asset_mark_id(&C, id)) {
+ stats.last_id = id;
+ stats.tot_created++;
+ }
+ }
+}
+
+bool AssetMarkHelper::wasSuccessful() const
+{
+ return stats.tot_created > 0;
+}
+
+void AssetMarkHelper::reportResults(ReportList &reports) const
+{
+ /* User feedback on failure. */
+ if (!wasSuccessful()) {
+ if ((stats.tot_already_asset > 0)) {
+ BKE_report(&reports,
+ RPT_ERROR,
+ "Selected data-blocks are already assets (or do not support use as assets)");
+ }
+ else {
+ BKE_report(&reports,
+ RPT_ERROR,
+ "No data-blocks to create assets for found (or do not support use as assets)");
+ }
+ }
+ /* User feedback on success. */
+ else if (stats.tot_created == 1) {
+ /* If only one data-block: Give more useful message by printing asset name. */
+ BKE_reportf(&reports, RPT_INFO, "Data-block '%s' is now an asset", stats.last_id->name + 2);
+ }
+ else {
+ BKE_reportf(&reports, RPT_INFO, "%i data-blocks are now assets", stats.tot_created);
+ }
+}
+
+static int asset_mark_exec(bContext *C, wmOperator *op)
+{
+ PointerRNAVec ids = asset_operation_get_ids_from_context(C);
+
+ AssetMarkHelper mark_helper;
+ mark_helper(*C, ids);
+ mark_helper.reportResults(*op->reports);
+
+ if (!mark_helper.wasSuccessful()) {
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_main_add_notifier(NC_ID | NA_EDITED, nullptr);
+ WM_main_add_notifier(NC_ASSET | NA_ADDED, nullptr);
+
+ return OPERATOR_FINISHED;
+}
+
+static void ASSET_OT_mark(wmOperatorType *ot)
+{
+ ot->name = "Mark Asset";
+ ot->description =
+ "Enable easier reuse of selected data-blocks through the Asset Browser, with the help of "
+ "customizable metadata (like previews, descriptions and tags)";
+ ot->idname = "ASSET_OT_mark";
+
+ ot->exec = asset_mark_exec;
+ ot->poll = asset_operation_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* -------------------------------------------------------------------- */
+
+class AssetClearHelper {
+ public:
+ void operator()(PointerRNAVec &ids);
+
+ void reportResults(ReportList &reports) const;
+ bool wasSuccessful() const;
+
+ private:
+ struct Stats {
+ int tot_cleared = 0;
+ ID *last_id = nullptr;
+ };
+
+ Stats stats;
+};
+
+void AssetClearHelper::operator()(PointerRNAVec &ids)
+{
+ for (PointerRNA &ptr : ids) {
+ BLI_assert(RNA_struct_is_ID(ptr.type));
+
+ ID *id = static_cast<ID *>(ptr.data);
+ if (!id->asset_data) {
+ continue;
+ }
+
+ if (ED_asset_clear_id(id)) {
+ stats.tot_cleared++;
+ stats.last_id = id;
+ }
+ }
+}
+
+void AssetClearHelper::reportResults(ReportList &reports) const
+{
+ if (!wasSuccessful()) {
+ BKE_report(&reports, RPT_ERROR, "No asset data-blocks selected/focused");
+ }
+ else if (stats.tot_cleared == 1) {
+ /* If only one data-block: Give more useful message by printing asset name. */
+ BKE_reportf(
+ &reports, RPT_INFO, "Data-block '%s' is no asset anymore", stats.last_id->name + 2);
+ }
+ else {
+ BKE_reportf(&reports, RPT_INFO, "%i data-blocks are no assets anymore", stats.tot_cleared);
+ }
+}
+
+bool AssetClearHelper::wasSuccessful() const
+{
+ return stats.tot_cleared > 0;
+}
+
+static int asset_clear_exec(bContext *C, wmOperator *op)
+{
+ PointerRNAVec ids = asset_operation_get_ids_from_context(C);
+
+ AssetClearHelper clear_helper;
+ clear_helper(ids);
+ clear_helper.reportResults(*op->reports);
+
+ if (!clear_helper.wasSuccessful()) {
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_main_add_notifier(NC_ID | NA_EDITED, nullptr);
+ WM_main_add_notifier(NC_ASSET | NA_REMOVED, nullptr);
+
+ return OPERATOR_FINISHED;
+}
+
+static void ASSET_OT_clear(wmOperatorType *ot)
+{
+ ot->name = "Clear Asset";
+ ot->description =
+ "Delete all asset metadata and turn the selected asset data-blocks back into normal "
+ "data-blocks";
+ ot->idname = "ASSET_OT_clear";
+
+ ot->exec = asset_clear_exec;
+ ot->poll = asset_operation_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* -------------------------------------------------------------------- */
+
+void ED_operatortypes_asset(void)
+{
+ WM_operatortype_append(ASSET_OT_mark);
+ WM_operatortype_append(ASSET_OT_clear);
+}
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index e9ceedf7ce2..8ebc2077619 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -2419,7 +2419,7 @@ static void adduplicateflagNurb(
memcpy(newnu->bp, &nu->bp[a], newu * newv * sizeof(BPoint));
memcpy(&newnu->bp[newu * newv], nu->bp, newu * cyclicv * sizeof(BPoint));
- /* check for actvert in cylicv selection */
+ /* check for actvert in cyclicv selection */
if (cu->actnu == i) {
calc_duplicate_actvert(
editnurb, newnurb, cu, cu->actvert, a, (newu * newv) + cu->actvert);
@@ -6102,7 +6102,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
}
if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
+ /* start and points copied if connecting segment was deleted and not cyclic spline */
bezt1 = nu->bezt;
bezt2 = &nu->bezt[1];
@@ -6232,7 +6232,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
}
if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
+ /* start and points copied if connecting segment was deleted and not cyclic spline */
bp1 = nu->bp;
bp2 = &nu->bp[1];
@@ -6352,7 +6352,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
}
if (!split && cut != -1 && nu->pntsv > 2 && !(nu->flagv & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
+ /* start and points copied if connecting segment was deleted and not cyclic spline */
bp1 = nu->bp;
bp2 = &nu->bp[nu->pntsu];
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index 4097275a2b9..82f7b456284 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -1242,7 +1242,7 @@ static void curve_select_random(ListBase *editnurb, float randfac, int seed, boo
static int curve_select_random_exec(bContext *C, wmOperator *op)
{
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
ViewLayer *view_layer = CTX_data_view_layer(C);
diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c
index 534d29c0cc7..681f387e83e 100644
--- a/source/blender/editors/curve/editcurve_undo.c
+++ b/source/blender/editors/curve/editcurve_undo.c
@@ -238,8 +238,11 @@ static bool curve_undosys_step_encode(struct bContext *C, struct Main *bmain, Un
return true;
}
-static void curve_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void curve_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
CurveUndoStep *us = (CurveUndoStep *)us_p;
diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c
index 8559234b62f..07f062e7a53 100644
--- a/source/blender/editors/curve/editfont_undo.c
+++ b/source/blender/editors/curve/editfont_undo.c
@@ -356,8 +356,11 @@ static bool font_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
return true;
}
-static void font_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void font_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
/* TODO(campbell): undo_system: use low-level API to set mode. */
ED_object_mode_set_ex(C, OB_MODE_EDIT, false, NULL);
diff --git a/source/blender/editors/geometry/geometry_attributes.c b/source/blender/editors/geometry/geometry_attributes.c
index 4106c03f17d..2807e7c4392 100644
--- a/source/blender/editors/geometry/geometry_attributes.c
+++ b/source/blender/editors/geometry/geometry_attributes.c
@@ -23,7 +23,6 @@
#include "BKE_attribute.h"
#include "BKE_context.h"
-#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -34,7 +33,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_geometry.h"
#include "ED_object.h"
#include "geometry_intern.h"
diff --git a/source/blender/editors/gizmo_library/gizmo_library_presets.c b/source/blender/editors/gizmo_library/gizmo_library_presets.c
index 9039851da01..4e56ceb9fd4 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_presets.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_presets.c
@@ -22,12 +22,9 @@
* \brief Preset shapes that can be drawn from any gizmo type.
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_math.h"
#include "DNA_object_types.h"
-#include "DNA_view3d_types.h"
#include "BKE_context.h"
@@ -36,12 +33,8 @@
#include "DEG_depsgraph.h"
-#include "RNA_access.h"
-
-#include "WM_api.h"
#include "WM_types.h"
-#include "ED_screen.h"
#include "ED_view3d.h"
/* own includes */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c
index 5617b6e125e..1b1f1151053 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c
@@ -28,14 +28,11 @@
#include "BKE_context.h"
#include "ED_gizmo_library.h"
-#include "ED_view3d.h"
#include "WM_api.h"
#include "WM_types.h"
/* own includes */
-#include "../gizmo_geometry.h"
-#include "../gizmo_library_intern.h"
static void gizmo_blank_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz))
{
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 eb40500d011..cbca230da7e 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
@@ -320,6 +320,16 @@ static int gizmo_button2d_cursor_get(wmGizmo *gz)
return WM_CURSOR_DEFAULT;
}
+static void gizmo_button2d_bounds(bContext *C, wmGizmo *gz, rcti *r_bounding_box)
+{
+ ScrArea *area = CTX_wm_area(C);
+ float rad = CIRCLE_RESOLUTION * U.dpi_fac / 2.0f;
+ r_bounding_box->xmin = gz->matrix_basis[3][0] + area->totrct.xmin - rad;
+ r_bounding_box->ymin = gz->matrix_basis[3][1] + area->totrct.ymin - rad;
+ r_bounding_box->xmax = r_bounding_box->xmin + rad;
+ r_bounding_box->ymax = r_bounding_box->ymin + rad;
+}
+
static void gizmo_button2d_free(wmGizmo *gz)
{
ButtonGizmo2D *shape = (ButtonGizmo2D *)gz;
@@ -346,6 +356,7 @@ static void GIZMO_GT_button_2d(wmGizmoType *gzt)
gzt->draw_select = gizmo_button2d_draw_select;
gzt->test_select = gizmo_button2d_test_select;
gzt->cursor_get = gizmo_button2d_cursor_get;
+ gzt->screen_bounds_get = gizmo_button2d_bounds;
gzt->free = gizmo_button2d_free;
gzt->struct_size = sizeof(ButtonGizmo2D);
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 4e2951c3571..751f8333aaa 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -171,7 +171,8 @@ static void gpencil_draw_stroke_3d(tGPDdraw *tgpw,
int totpoints = tgpw->gps->totpoints;
const float viewport[2] = {(float)tgpw->winx, (float)tgpw->winy};
- float curpressure = points[0].pressure;
+ const float min_thickness = 0.05f;
+
float fpt[3];
/* if cyclic needs more vertex */
@@ -205,7 +206,6 @@ static void gpencil_draw_stroke_3d(tGPDdraw *tgpw,
immUniform1i("fill_stroke", (int)tgpw->is_fill_stroke);
/* draw stroke curve */
- GPU_line_width(max_ff(curpressure * thickness, 1.0f));
immBeginAtMost(GPU_PRIM_LINE_STRIP_ADJ, totpoints + cyclic_add + 2);
const bGPDspoint *pt = points;
@@ -215,18 +215,19 @@ static void gpencil_draw_stroke_3d(tGPDdraw *tgpw,
gpencil_set_point_varying_color(points, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
if ((cyclic) && (totpoints > 2)) {
- immAttr1f(attr_id.thickness, max_ff((points + totpoints - 1)->pressure * thickness, 1.0f));
+ immAttr1f(attr_id.thickness,
+ max_ff((points + totpoints - 1)->pressure * thickness, min_thickness));
mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + totpoints - 1)->x);
}
else {
- immAttr1f(attr_id.thickness, max_ff((points + 1)->pressure * thickness, 1.0f));
+ immAttr1f(attr_id.thickness, max_ff((points + 1)->pressure * thickness, min_thickness));
mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + 1)->x);
}
immVertex3fv(attr_id.pos, fpt);
}
/* set point */
gpencil_set_point_varying_color(pt, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
- immAttr1f(attr_id.thickness, max_ff(pt->pressure * thickness, 1.0f));
+ immAttr1f(attr_id.thickness, max_ff(pt->pressure * thickness, min_thickness));
mul_v3_m4v3(fpt, tgpw->diff_mat, &pt->x);
immVertex3fv(attr_id.pos, fpt);
}
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index aae31b11025..166111c582c 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -276,7 +276,7 @@ void ED_gpencil_layer_frames_duplicate(bGPDlayer *gpl)
bGPDframe *gpfd;
/* duplicate frame, and deselect self */
- gpfd = BKE_gpencil_frame_duplicate(gpf);
+ gpfd = BKE_gpencil_frame_duplicate(gpf, true);
gpf->flag &= ~GP_FRAME_SELECT;
BLI_insertlinkafter(&gpl->frames, gpf, gpfd);
@@ -361,7 +361,7 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
/* if frame is selected, make duplicate it and its strokes */
if (gpf->flag & GP_FRAME_SELECT) {
/* make a copy of this frame */
- bGPDframe *new_frame = BKE_gpencil_frame_duplicate(gpf);
+ bGPDframe *new_frame = BKE_gpencil_frame_duplicate(gpf, true);
BLI_addtail(&copied_frames, new_frame);
/* extend extents for keyframes encountered */
diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c
index 65141442237..d86bad7ef3c 100644
--- a/source/blender/editors/gpencil/gpencil_add_monkey.c
+++ b/source/blender/editors/gpencil/gpencil_add_monkey.c
@@ -29,16 +29,13 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
-#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "ED_gpencil.h"
diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c
index 0c8cc621a3b..1e1a70f9c1d 100644
--- a/source/blender/editors/gpencil/gpencil_add_stroke.c
+++ b/source/blender/editors/gpencil/gpencil_add_stroke.c
@@ -29,16 +29,13 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
-#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "ED_gpencil.h"
diff --git a/source/blender/editors/gpencil/gpencil_armature.c b/source/blender/editors/gpencil/gpencil_armature.c
index 5cc5e7ecdcd..3271096c433 100644
--- a/source/blender/editors/gpencil/gpencil_armature.c
+++ b/source/blender/editors/gpencil/gpencil_armature.c
@@ -31,12 +31,9 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "DNA_armature_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_meshdata_types.h"
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 09b57029350..ac75ae44c8a 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -178,7 +178,7 @@ static void gpencil_strokepoint_convertcoords(bContext *C,
/* apply parent transform */
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
mul_v3_m4v3(fpt, diff_mat, &source_pt->x);
copy_v3_v3(&pt->x, fpt);
@@ -370,7 +370,7 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd,
static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
RNG *rng,
int *nbr_gaps,
- float *tot_gaps_time)
+ float *r_tot_gaps_time)
{
float delta_time = 0.0f;
@@ -387,10 +387,10 @@ static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
}
gtd->tot_time -= delta_time;
- *tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration;
- gtd->tot_time += *tot_gaps_time;
+ *r_tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration;
+ gtd->tot_time += *r_tot_gaps_time;
if (G.debug & G_DEBUG) {
- printf("%f, %f, %f, %d\n", gtd->tot_time, delta_time, *tot_gaps_time, *nbr_gaps);
+ printf("%f, %f, %f, %d\n", gtd->tot_time, delta_time, *r_tot_gaps_time, *nbr_gaps);
}
if (gtd->gap_randomness > 0.0f) {
BLI_rng_srandom(rng, gtd->seed);
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index ad9b72b713e..3be913f342d 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -449,21 +449,32 @@ void GPENCIL_OT_layer_annotation_move(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
}
/* ********************* Duplicate Layer ************************** */
+enum {
+ GP_LAYER_DUPLICATE_ALL = 0,
+ GP_LAYER_DUPLICATE_EMPTY = 1,
+};
-static int gpencil_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_layer_copy_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
bGPDlayer *new_layer;
-
+ const int mode = RNA_enum_get(op->ptr, "mode");
+ const bool dup_strokes = (bool)(mode == GP_LAYER_DUPLICATE_ALL);
/* sanity checks */
if (ELEM(NULL, gpd, gpl)) {
return OPERATOR_CANCELLED;
}
- /* make copy of layer, and add it immediately after the existing layer */
- new_layer = BKE_gpencil_layer_duplicate(gpl);
- BLI_insertlinkafter(&gpd->layers, gpl, new_layer);
+ /* Make copy of layer, and add it immediately after or before the existing layer. */
+ new_layer = BKE_gpencil_layer_duplicate(gpl, true, dup_strokes);
+ if (dup_strokes) {
+ BLI_insertlinkafter(&gpd->layers, gpl, new_layer);
+ }
+ else {
+ /* For empty strokes is better add below. */
+ BLI_insertlinkbefore(&gpd->layers, gpl, new_layer);
+ }
/* ensure new layer has a unique name, and is now the active layer */
BLI_uniquename(&gpd->layers,
@@ -484,6 +495,12 @@ static int gpencil_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
{
+ static const EnumPropertyItem copy_mode[] = {
+ {GP_LAYER_DUPLICATE_ALL, "ALL", 0, "All Data", ""},
+ {GP_LAYER_DUPLICATE_EMPTY, "EMPTY", 0, "Empty Keyframes", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
/* identifiers */
ot->name = "Duplicate Layer";
ot->idname = "GPENCIL_OT_layer_duplicate";
@@ -495,6 +512,8 @@ void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "mode", copy_mode, GP_LAYER_DUPLICATE_ALL, "Mode", "");
}
/* ********************* Duplicate Layer in a new object ************************** */
@@ -1560,7 +1579,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* some stroke is already at front*/
@@ -1725,7 +1744,7 @@ static int gpencil_stroke_change_color_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2849,12 +2868,12 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
mul_v3_m3v3(offset_local, imat, offset_global);
LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd_src->layers) {
- bGPDlayer *gpl_new = BKE_gpencil_layer_duplicate(gpl_src);
+ bGPDlayer *gpl_new = BKE_gpencil_layer_duplicate(gpl_src, true, true);
float diff_mat[4][4];
float inverse_diff_mat[4][4];
/* recalculate all stroke points */
- BKE_gpencil_parent_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
invert_m4_m4_safe_ortho(inverse_diff_mat, diff_mat);
Material *ma_src = NULL;
@@ -3388,7 +3407,7 @@ static int gpencil_material_select_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index d1c8eca1be0..aeff2acb04d 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1867,7 +1867,7 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2610,7 +2610,7 @@ static int gpencil_delete_selected_points(bContext *C)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2800,7 +2800,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
float diff_mat[4][4];
/* calculate difference matrix object */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* skip strokes that are invalid for current view */
@@ -2808,7 +2808,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
@@ -2935,7 +2935,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
float diff_mat[4][4];
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
bGPDspoint *pt;
@@ -2946,7 +2946,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
@@ -3039,7 +3039,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
float diff_mat[4][4];
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
bGPDspoint *pt;
@@ -3050,7 +3050,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
@@ -3565,7 +3565,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
elem = &strokes_list[tot_strokes];
@@ -3697,7 +3697,7 @@ static int gpencil_stroke_flip_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -4516,7 +4516,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Separate selected strokes. */
@@ -4717,7 +4717,7 @@ static int gpencil_stroke_split_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Split selected strokes. */
@@ -4948,11 +4948,14 @@ static int gpencil_cutter_lasso_select(bContext *C,
GPencilTestFn is_inside_fn,
void *user_data)
{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Object *obact = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
ScrArea *area = CTX_wm_area(C);
ToolSettings *ts = CTX_data_tool_settings(C);
const float scale = ts->gp_sculpt.isect_threshold;
const bool flat_caps = RNA_boolean_get(op->ptr, "flat_caps");
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
bGPDspoint *pt;
GP_SpaceConversion gsc = {NULL};
@@ -4979,57 +4982,87 @@ static int gpencil_cutter_lasso_select(bContext *C,
}
CTX_DATA_END;
- /* select points */
- GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
- int tot_inside = 0;
- const int oldtot = gps->totpoints;
- for (int i = 0; i < gps->totpoints; i++) {
- pt = &gps->points[i];
- if ((pt->flag & GP_SPOINT_SELECT) || (pt->flag & GP_SPOINT_TAG)) {
- continue;
- }
- /* convert point coords to screen-space */
- const bool is_inside = is_inside_fn(gps, pt, &gsc, gpstroke_iter.diff_mat, user_data);
- if (is_inside) {
- tot_inside++;
- changed = true;
- pt->flag |= GP_SPOINT_SELECT;
- gps->flag |= GP_STROKE_SELECT;
- float r_hita[3], r_hitb[3];
- if (gps->totpoints > 1) {
- ED_gpencil_select_stroke_segment(gpd, gpl, gps, pt, true, true, scale, r_hita, r_hitb);
+ /* Select points */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ if ((gpl->flag & GP_LAYER_LOCKED) || ((gpl->flag & GP_LAYER_HIDE))) {
+ continue;
+ }
+
+ float diff_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ } /* check if the color is editable */
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
+ continue;
+ }
+ int tot_inside = 0;
+ const int oldtot = gps->totpoints;
+ for (int i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ if ((pt->flag & GP_SPOINT_SELECT) || (pt->flag & GP_SPOINT_TAG)) {
+ continue;
+ }
+ /* convert point coords to screen-space */
+ const bool is_inside = is_inside_fn(gps, pt, &gsc, diff_mat, user_data);
+ if (is_inside) {
+ tot_inside++;
+ changed = true;
+ pt->flag |= GP_SPOINT_SELECT;
+ gps->flag |= GP_STROKE_SELECT;
+ float r_hita[3], r_hitb[3];
+ if (gps->totpoints > 1) {
+ ED_gpencil_select_stroke_segment(
+ gpd, gpl, gps, pt, true, true, scale, r_hita, r_hitb);
+ }
+ /* avoid infinite loops */
+ if (gps->totpoints > oldtot) {
+ break;
+ }
+ }
+ }
+ /* if mark all points inside lasso set to remove all stroke */
+ if ((tot_inside == oldtot) || ((tot_inside == 1) && (oldtot == 2))) {
+ for (int i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ }
}
- /* avoid infinite loops */
- if (gps->totpoints > oldtot) {
+ /* if not multiedit, exit loop. */
+ if (!is_multiedit) {
break;
}
}
}
- /* if mark all points inside lasso set to remove all stroke */
- if ((tot_inside == oldtot) || ((tot_inside == 1) && (oldtot == 2))) {
- for (int i = 0; i < gps->totpoints; i++) {
- pt = &gps->points[i];
- pt->flag |= GP_SPOINT_SELECT;
- }
- }
}
- GP_EDITABLE_STROKES_END(gpstroke_iter);
- /* dissolve selected points */
+ /* Dissolve selected points. */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- if (gpl->flag & GP_LAYER_LOCKED) {
- continue;
- }
-
- bGPDframe *gpf = gpl->actframe;
- if (gpf == NULL) {
- continue;
- }
- LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
- if (gps->flag & GP_STROKE_SELECT) {
- gpencil_cutter_dissolve(gpd, gpl, gps, flat_caps);
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+ bGPDframe *gpf_act = gpl->actframe;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ gpl->actframe = gpf;
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ if (gps->flag & GP_STROKE_SELECT) {
+ gpencil_cutter_dissolve(gpd, gpl, gps, flat_caps);
+ }
+ }
+ /* if not multiedit, exit loop. */
+ if (!is_multiedit) {
+ break;
}
}
+ gpl->actframe = gpf_act;
}
/* updates */
diff --git a/source/blender/editors/gpencil/gpencil_edit_curve.c b/source/blender/editors/gpencil/gpencil_edit_curve.c
index 60d1d2169b4..031bbd61173 100644
--- a/source/blender/editors/gpencil/gpencil_edit_curve.c
+++ b/source/blender/editors/gpencil/gpencil_edit_curve.c
@@ -28,13 +28,10 @@
#include <stdlib.h>
#include <string.h>
-#include "MEM_guardedalloc.h"
-
#include "DNA_gpencil_types.h"
#include "DNA_view3d_types.h"
#include "BKE_context.h"
-#include "BKE_curve.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_curve.h"
#include "BKE_gpencil_geom.h"
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 8bd0b2f86de..832191c8321 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_stack.h"
#include "BLI_utildefines.h"
@@ -81,8 +82,18 @@
#define LEAK_HORZ 0
#define LEAK_VERT 1
+#define MIN_WINDOW_SIZE 128
-/* Temporary fill operation data (op->customdata) */
+/* Set to 1 to debug filling internal image. By default, the value must be 0. */
+#define FILL_DEBUG 0
+
+/* Duplicated: etempFlags */
+enum {
+ GP_DRAWFILLS_NOSTATUS = (1 << 0), /* don't draw status info */
+ GP_DRAWFILLS_ONLY3D = (1 << 1), /* only draw 3d-strokes */
+};
+
+/* Temporary fill operation data `op->customdata`. */
typedef struct tGPDfill {
bContext *C;
struct Main *bmain;
@@ -101,7 +112,7 @@ typedef struct tGPDfill {
struct View3D *v3d;
/** region where painting originated */
struct ARegion *region;
- /** current GP datablock */
+ /** Current GP data-block. */
struct bGPdata *gpd;
/** current material */
struct Material *mat;
@@ -111,6 +122,8 @@ typedef struct tGPDfill {
struct bGPDlayer *gpl;
/** frame */
struct bGPDframe *gpf;
+ /** Temp mouse position stroke. */
+ struct bGPDstroke *gps_mouse;
/** flags */
short flag;
@@ -118,9 +131,12 @@ typedef struct tGPDfill {
short oldkey;
/** send to back stroke */
bool on_back;
-
+ /** Flag for render mode */
+ bool is_render;
+ /** Flag to check something was done. */
+ bool done;
/** mouse fill center position */
- int center[2];
+ int mouse[2];
/** windows width */
int sizex;
/** window height */
@@ -137,7 +153,7 @@ typedef struct tGPDfill {
/** boundary limits drawing mode */
int fill_draw_mode;
/* scaling factor */
- short fill_factor;
+ float fill_factor;
/* Frame to use. */
int active_cfra;
@@ -156,14 +172,184 @@ typedef struct tGPDfill {
/** handle for drawing strokes while operator is running 3d stuff */
void *draw_handle_3d;
- /* tmp size x */
+ /* Temporary size x. */
int bwinx;
- /* tmp size y */
+ /* Temporary size y. */
int bwiny;
rcti brect;
+ /* Space Conversion Data */
+ GP_SpaceConversion gsc;
+
+ /** Zoom factor. */
+ float zoom;
+
+ /** Factor of extension. */
+ float fill_extend_fac;
+
} 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);
+
+/* Delete any temporary stroke. */
+static void gpencil_delete_temp_stroke_extension(tGPDfill *tgpf, const bool all_frames)
+{
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &tgpf->gpd->layers) {
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+
+ bGPDframe *init_gpf = (all_frames) ? gpl->frames.first :
+ BKE_gpencil_layer_frame_get(
+ gpl, tgpf->active_cfra, GP_GETFRAME_USE_PREV);
+ if (init_gpf == NULL) {
+ continue;
+ }
+ 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)) {
+ BLI_remlink(&gpf->strokes, gps);
+ BKE_gpencil_free_stroke(gps);
+ }
+ }
+ if (!all_frames) {
+ break;
+ }
+ }
+ }
+}
+
+static void extrapolate_points_by_length(bGPDspoint *a,
+ bGPDspoint *b,
+ float length,
+ float r_point[3])
+{
+ float ab[3];
+ sub_v3_v3v3(ab, &b->x, &a->x);
+ normalize_v3(ab);
+ mul_v3_fl(ab, length);
+ add_v3_v3v3(r_point, &b->x, ab);
+}
+
+/* Loop all layers create stroke extensions. */
+static void gpencil_create_extensions(tGPDfill *tgpf)
+{
+ Object *ob = tgpf->ob;
+ 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);
+
+ 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;
+ }
+
+ 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;
+ }
+
+ /* Extend start. */
+ 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);
+ }
+ }
+}
+
+static void gpencil_update_extend(tGPDfill *tgpf)
+{
+ gpencil_delete_temp_stroke_extension(tgpf, false);
+
+ if (tgpf->fill_extend_fac > 0.0f) {
+ gpencil_create_extensions(tgpf);
+ }
+ WM_event_add_notifier(tgpf->C, NC_GPENCIL | NA_EDITED, NULL);
+}
+
+static bool gpencil_stroke_is_drawable(tGPDfill *tgpf, bGPDstroke *gps)
+{
+ 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) {
+ return false;
+ }
+ }
+
+ if ((show_help) && (!show_extend)) {
+ if (is_extend) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
/* draw a given stroke using same thickness and color for all points */
static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
bGPDstroke *gps,
@@ -171,7 +357,8 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
const bool cyclic,
const float ink[4],
const int flag,
- const float thershold)
+ const float thershold,
+ const float thickness)
{
bGPDspoint *points = gps->points;
@@ -181,9 +368,19 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
int totpoints = gps->totpoints;
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);
- copy_v4_v4(col, ink);
+ if (!gpencil_stroke_is_drawable(tgpf, gps)) {
+ return;
+ }
+ if ((is_extend) && (!tgpf->is_render)) {
+ copy_v4_v4(col, extend_col);
+ }
+ else {
+ copy_v4_v4(col, ink);
+ }
/* if cyclic needs more vertex */
int cyclic_add = (cyclic) ? 1 : 0;
@@ -194,7 +391,7 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
/* draw stroke curve */
- GPU_line_width(1.0f);
+ GPU_line_width((!is_extend) ? thickness : thickness * 2.0f);
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add);
const bGPDspoint *pt = points;
@@ -225,15 +422,77 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
immUnbindProgram();
}
-/* loop all layers */
-static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
+static void draw_mouse_position(tGPDfill *tgpf)
{
- /* duplicated: etempFlags */
- enum {
- GP_DRAWFILLS_NOSTATUS = (1 << 0), /* don't draw status info */
- GP_DRAWFILLS_ONLY3D = (1 << 1), /* only draw 3d-strokes */
- };
+ if (tgpf->gps_mouse == NULL) {
+ return;
+ }
+ uchar mouse_color[4] = {0, 0, 255, 255};
+ bGPDspoint *pt = &tgpf->gps_mouse->points[0];
+ float point_size = (tgpf->zoom == 1.0f) ? 4.0f * tgpf->fill_factor :
+ (0.5f * tgpf->zoom) + tgpf->fill_factor;
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ /* Draw mouse click position in Blue. */
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+ GPU_point_size(point_size);
+ immBegin(GPU_PRIM_POINTS, 1);
+ immAttr4ubv(col, mouse_color);
+ immVertex3fv(pos, &pt->x);
+ immEnd();
+ immUnbindProgram();
+}
+
+/* Helper: Check if must skip the layer */
+bool skip_layer_check(short fill_layer_mode, int gpl_active_index, int gpl_index)
+{
+ bool skip = false;
+
+ switch (fill_layer_mode) {
+ case GP_FILL_GPLMODE_ACTIVE: {
+ if (gpl_index != gpl_active_index) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ABOVE: {
+ if (gpl_index != gpl_active_index + 1) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_BELOW: {
+ if (gpl_index != gpl_active_index - 1) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ALL_ABOVE: {
+ if (gpl_index <= gpl_active_index) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ALL_BELOW: {
+ if (gpl_index >= gpl_active_index) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_VISIBLE:
+ default:
+ break;
+ }
+
+ return skip;
+}
+
+/* Loop all layers to draw strokes. */
+static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
+{
Object *ob = tgpf->ob;
bGPdata *gpd = tgpf->gpd;
Brush *brush = tgpf->brush;
@@ -247,8 +506,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
tgpw.gpd = gpd;
tgpw.offsx = 0;
tgpw.offsy = 0;
- tgpw.winx = tgpf->region->winx;
- tgpw.winy = tgpf->region->winy;
+ tgpw.winx = tgpf->sizex;
+ tgpw.winy = tgpf->sizey;
tgpw.dflag = 0;
tgpw.disable_fill = 1;
tgpw.dflag |= (GP_DRAWFILLS_ONLY3D | GP_DRAWFILLS_NOSTATUS);
@@ -261,54 +520,22 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
BLI_assert(gpl_active_index >= 0);
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* calculate parent position */
- BKE_gpencil_parent_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
+ /* Draw blue point where click with mouse. */
+ draw_mouse_position(tgpf);
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* do not draw layer if hidden */
if (gpl->flag & GP_LAYER_HIDE) {
continue;
}
+ /* calculate parent position */
+ BKE_gpencil_layer_transform_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
+
/* Decide if the strokes of layers are included or not depending on the layer mode.
* Cannot skip the layer because it can use boundary strokes and must be used. */
- bool skip = false;
const int gpl_index = BLI_findindex(&gpd->layers, gpl);
- switch (brush_settings->fill_layer_mode) {
- case GP_FILL_GPLMODE_ACTIVE: {
- if (gpl_index != gpl_active_index) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_ABOVE: {
- if (gpl_index != gpl_active_index + 1) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_BELOW: {
- if (gpl_index != gpl_active_index - 1) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_ALL_ABOVE: {
- if (gpl_index <= gpl_active_index) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_ALL_BELOW: {
- if (gpl_index >= gpl_active_index) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_VISIBLE:
- default:
- break;
- }
+ bool skip = skip_layer_check(brush_settings->fill_layer_mode, gpl_active_index, gpl_index);
/* if active layer and no keyframe, create a new one */
if (gpl == tgpf->gpl) {
@@ -351,17 +578,19 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
tgpw.gpf = gpf;
tgpw.t_gpf = gpf;
- /* reduce thickness to avoid gaps */
tgpw.is_fill_stroke = (tgpf->fill_draw_mode == GP_FILL_DMODE_CONTROL) ? false : true;
+ /* Reduce thickness to avoid gaps. */
tgpw.lthick = gpl->line_change;
tgpw.opacity = 1.0;
copy_v4_v4(tgpw.tintcolor, ink);
tgpw.onion = true;
tgpw.custonion = true;
- /* normal strokes */
+ /* Normal strokes. */
if (ELEM(tgpf->fill_draw_mode, GP_FILL_DMODE_STROKE, GP_FILL_DMODE_BOTH)) {
- ED_gpencil_draw_fill(&tgpw);
+ if (gpencil_stroke_is_drawable(tgpf, gps) && ((gps->flag & GP_STROKE_TAG) == 0)) {
+ ED_gpencil_draw_fill(&tgpw);
+ }
}
/* 3D Lines with basic shapes and invisible lines */
@@ -372,7 +601,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
gps->flag & GP_STROKE_CYCLIC,
ink,
tgpf->flag,
- tgpf->fill_threshold);
+ tgpf->fill_threshold,
+ 1.0f);
}
}
}
@@ -380,7 +610,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
GPU_blend(GPU_BLEND_NONE);
}
-/* draw strokes in offscreen buffer */
+/* Draw strokes in off-screen buffer. */
static bool gpencil_render_offscreen(tGPDfill *tgpf)
{
bool is_ortho = false;
@@ -391,15 +621,15 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
}
/* set temporary new size */
- tgpf->bwinx = tgpf->region->winx;
- tgpf->bwiny = tgpf->region->winy;
+ tgpf->bwinx = tgpf->region->sizex;
+ tgpf->bwiny = tgpf->region->sizey;
tgpf->brect = tgpf->region->winrct;
/* resize region */
tgpf->region->winrct.xmin = 0;
tgpf->region->winrct.ymin = 0;
- tgpf->region->winrct.xmax = (int)tgpf->region->winx * tgpf->fill_factor;
- tgpf->region->winrct.ymax = (int)tgpf->region->winy * tgpf->fill_factor;
+ tgpf->region->winrct.xmax = max_ii((int)tgpf->region->winx * tgpf->fill_factor, MIN_WINDOW_SIZE);
+ tgpf->region->winrct.ymax = max_ii((int)tgpf->region->winy * tgpf->fill_factor, MIN_WINDOW_SIZE);
tgpf->region->winx = (short)abs(tgpf->region->winrct.xmax - tgpf->region->winrct.xmin);
tgpf->region->winy = (short)abs(tgpf->region->winrct.ymax - tgpf->region->winrct.ymin);
@@ -407,12 +637,6 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
tgpf->sizex = (int)tgpf->region->winx;
tgpf->sizey = (int)tgpf->region->winy;
- /* adjust center */
- float center[2];
- center[0] = (float)tgpf->center[0] * ((float)tgpf->region->winx / (float)tgpf->bwinx);
- center[1] = (float)tgpf->center[1] * ((float)tgpf->region->winy / (float)tgpf->bwiny);
- round_v2i_v2fl(tgpf->center, center);
-
char err_out[256] = "unknown";
GPUOffScreen *offscreen = GPU_offscreen_create(tgpf->sizex, tgpf->sizey, true, false, err_out);
if (offscreen == NULL) {
@@ -421,7 +645,7 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
}
GPU_offscreen_bind(offscreen, true);
- uint flag = IB_rect | IB_rectfloat;
+ uint flag = IB_rectfloat;
ImBuf *ibuf = IMB_allocImBuf(tgpf->sizex, tgpf->sizey, 32, flag);
rctf viewplane;
@@ -436,6 +660,21 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
&clip_start,
&clip_end,
NULL);
+
+ /* Rescale `viewplane` to fit all strokes. */
+ float width = viewplane.xmax - viewplane.xmin;
+ float height = viewplane.ymax - viewplane.ymin;
+
+ float width_new = width * tgpf->zoom;
+ float height_new = height * tgpf->zoom;
+ float scale_x = (width_new - width) / 2.0f;
+ float scale_y = (height_new - height) / 2.0f;
+
+ viewplane.xmin -= scale_x;
+ viewplane.xmax += scale_x;
+ viewplane.ymin -= scale_y;
+ viewplane.ymax += scale_y;
+
if (is_ortho) {
orthographic_m4(winmat,
viewplane.xmin,
@@ -456,7 +695,7 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
}
GPU_matrix_push_projection();
- GPU_matrix_identity_set();
+ GPU_matrix_identity_projection_set();
GPU_matrix_push();
GPU_matrix_identity_set();
@@ -495,45 +734,33 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
BKE_image_release_ibuf(tgpf->ima, ibuf, NULL);
- /* switch back to window-system-provided framebuffer */
+ /* Switch back to window-system-provided frame-buffer. */
GPU_offscreen_unbind(offscreen, true);
GPU_offscreen_free(offscreen);
return true;
}
-/* return pixel data (rgba) at index */
+/* Return pixel data (RGBA) at index. */
static void get_pixel(const ImBuf *ibuf, const int idx, float r_col[4])
{
- if (ibuf->rect_float) {
- const float *frgba = &ibuf->rect_float[idx * 4];
- copy_v4_v4(r_col, frgba);
- }
- else {
- /* XXX: This case probably doesn't happen, as we only write to the float buffer,
- * but we get compiler warnings about uninitialized vars otherwise
- */
- BLI_assert(!"gpencil_fill.c - get_pixel() non-float case is used!");
- zero_v4(r_col);
- }
+ BLI_assert(ibuf->rect_float != NULL);
+ memcpy(r_col, &ibuf->rect_float[idx * 4], sizeof(float[4]));
}
-/* set pixel data (rgba) at index */
+/* Set pixel data (RGBA) at index. */
static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
{
- // BLI_assert(idx <= ibuf->x * ibuf->y);
- if (ibuf->rect) {
- uint *rrect = &ibuf->rect[idx];
- uchar ccol[4];
-
- rgba_float_to_uchar(ccol, col);
- *rrect = *((uint *)ccol);
- }
+ BLI_assert(ibuf->rect_float != NULL);
+ float *rrectf = &ibuf->rect_float[idx * 4];
+ copy_v4_v4(rrectf, col);
+}
- if (ibuf->rect_float) {
- float *rrectf = &ibuf->rect_float[idx * 4];
- copy_v4_v4(rrectf, col);
- }
+/* Helper: Check if one image row is empty. */
+static bool is_row_filled(const ImBuf *ibuf, const int row_index)
+{
+ float *row = &ibuf->rect_float[ibuf->x * 4 * row_index];
+ return (row[0] == 0.0f && memcmp(row, row + 1, ((ibuf->x * 4) - 1) * sizeof(float)) != 0);
}
/**
@@ -541,6 +768,9 @@ static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
* this is used for strokes with small gaps between them to get a full fill
* and do not get a full screen fill.
*
+ * This function assumes that if the furthest pixel is occupied,
+ * the other pixels are occupied.
+ *
* \param ibuf: Image pixel data.
* \param maxpixel: Maximum index.
* \param limit: Limit of pixels to analyze.
@@ -550,10 +780,10 @@ static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index, int type)
{
float rgba[4];
- int i;
int pt;
bool t_a = false;
bool t_b = false;
+ const int extreme = limit - 1;
/* Horizontal leak (check vertical pixels)
* X
@@ -564,37 +794,29 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index
*/
if (type == LEAK_HORZ) {
/* pixels on top */
- for (i = 1; i <= limit; i++) {
- pt = index + (ibuf->x * i);
- if (pt <= maxpixel) {
- get_pixel(ibuf, pt, rgba);
- if (rgba[0] == 1.0f) {
- t_a = true;
- break;
- }
- }
- else {
- /* edge of image*/
+ pt = index + (ibuf->x * extreme);
+ if (pt <= maxpixel) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
t_a = true;
- break;
}
}
+ else {
+ /* edge of image*/
+ t_a = true;
+ }
/* pixels on bottom */
- for (i = 1; i <= limit; i++) {
- pt = index - (ibuf->x * i);
- if (pt >= 0) {
- get_pixel(ibuf, pt, rgba);
- if (rgba[0] == 1.0f) {
- t_b = true;
- break;
- }
- }
- else {
- /* edge of image*/
+ pt = index - (ibuf->x * extreme);
+ if (pt >= 0) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
t_b = true;
- break;
}
}
+ else {
+ /* edge of image*/
+ t_b = true;
+ }
}
/* Vertical leak (check horizontal pixels)
@@ -608,35 +830,27 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index
int higpix = lowpix + ibuf->x - 1;
/* pixels to right */
- for (i = 0; i < limit; i++) {
- pt = index - (limit - i);
- if (pt >= lowpix) {
- get_pixel(ibuf, pt, rgba);
- if (rgba[0] == 1.0f) {
- t_a = true;
- break;
- }
- }
- else {
- t_a = true; /* edge of image*/
- break;
+ pt = index - extreme;
+ if (pt >= lowpix) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
+ t_a = true;
}
}
+ else {
+ t_a = true; /* edge of image*/
+ }
/* pixels to left */
- for (i = 0; i < limit; i++) {
- pt = index + (limit - i);
- if (pt <= higpix) {
- get_pixel(ibuf, pt, rgba);
- if (rgba[0] == 1.0f) {
- t_b = true;
- break;
- }
- }
- else {
- t_b = true; /* edge of image */
- break;
+ pt = index + extreme;
+ if (pt <= higpix) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
+ t_b = true;
}
}
+ else {
+ t_b = true; /* edge of image */
+ }
}
return (bool)(t_a && t_b);
}
@@ -659,23 +873,37 @@ static void gpencil_boundaryfill_area(tGPDfill *tgpf)
BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__);
- /* calculate index of the seed point using the position of the mouse */
- int index = (tgpf->sizex * tgpf->center[1]) + tgpf->center[0];
+ /* Calculate index of the seed point using the position of the mouse looking
+ * for a blue pixel. */
+ int index = -1;
+ for (int i = 0; i < maxpixel; i++) {
+ get_pixel(ibuf, i, rgba);
+ if (rgba[2] == 1.0f) {
+ index = i;
+ break;
+ }
+ }
+
if ((index >= 0) && (index <= maxpixel)) {
- BLI_stack_push(stack, &index);
+ if (!FILL_DEBUG) {
+ BLI_stack_push(stack, &index);
+ }
}
- /* the fill use a stack to save the pixel list instead of the common recursive
+ /**
+ * The fill use a stack to save the pixel list instead of the common recursive
* 4-contact point method.
* The problem with recursive calls is that for big fill areas, we can get max limit
* of recursive calls and STACK_OVERFLOW error.
*
* The 4-contact point analyze the pixels to the left, right, bottom and top
- * -----------
- * | X |
- * | XoX |
- * | X |
- * -----------
+ * <pre>
+ * -----------
+ * | X |
+ * | XoX |
+ * | X |
+ * -----------
+ * </pre>
*/
while (!BLI_stack_is_empty(stack)) {
int v;
@@ -763,7 +991,7 @@ static void gpencil_set_borders(tGPDfill *tgpf, const bool transparent)
tgpf->ima->id.tag |= LIB_TAG_DOIT;
}
-/* Invert image to paint invese area. */
+/* Invert image to paint inverse area. */
static void gpencil_invert_image(tGPDfill *tgpf)
{
ImBuf *ibuf;
@@ -773,18 +1001,24 @@ static void gpencil_invert_image(tGPDfill *tgpf)
ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
const int maxpixel = (ibuf->x * ibuf->y) - 1;
+ const int center = ibuf->x / 2;
for (int v = maxpixel; v != 0; v--) {
float color[4];
get_pixel(ibuf, v, color);
- /* Green. */
+ /* Green->Red. */
if (color[1] == 1.0f) {
set_pixel(ibuf, v, fill_col[0]);
}
+ /* Red->Green */
else if (color[0] == 1.0f) {
set_pixel(ibuf, v, fill_col[1]);
+ /* Add thickness of 2 pixels to avoid too thin lines. */
+ int offset = (v % ibuf->x < center) ? 1 : -1;
+ set_pixel(ibuf, v + offset, fill_col[1]);
}
else {
+ /* Set to Transparent. */
set_pixel(ibuf, v, fill_col[2]);
}
}
@@ -821,21 +1055,37 @@ static void gpencil_erase_processed_area(tGPDfill *tgpf)
float rgba[4];
for (int idy = 0; idy < ibuf->y; idy++) {
- bool clear = false;
+ int init = -1;
+ int end = -1;
for (int idx = 0; idx < ibuf->x; idx++) {
int image_idx = ibuf->x * idy + idx;
get_pixel(ibuf, image_idx, rgba);
/* Blue. */
if (rgba[2] == 1.0f) {
- clear = true;
+ if (init < 0) {
+ init = image_idx;
+ }
+ else {
+ end = image_idx;
+ }
}
/* Red. */
else if (rgba[0] == 1.0f) {
- clear = false;
+ if (init > -1) {
+ for (int i = init; i <= max_ii(init, end); i++) {
+ set_pixel(ibuf, i, clear_col);
+ }
+ init = -1;
+ end = -1;
+ }
}
- if (clear) {
- set_pixel(ibuf, image_idx, clear_col);
+ }
+ /* Check last segment. */
+ if (init > -1) {
+ for (int i = init; i <= max_ii(init, end); i++) {
+ set_pixel(ibuf, i, clear_col);
}
+ set_pixel(ibuf, init, clear_col);
}
}
@@ -845,98 +1095,112 @@ static void gpencil_erase_processed_area(tGPDfill *tgpf)
tgpf->ima->id.tag |= LIB_TAG_DOIT;
}
-/* Naive dilate
+/**
+ * Naive dilate
*
* Expand green areas into enclosing red areas.
* Using stack prevents creep when replacing colors directly.
+ * <pre>
* -----------
* XXXXXXX
* XoooooX
* XXooXXX
* XXXX
* -----------
+ * </pre>
*/
-static void dilate_shape(ImBuf *ibuf)
+static bool dilate_shape(ImBuf *ibuf)
{
+ bool done = false;
+
BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__);
const float green[4] = {0.0f, 1.0f, 0.0f, 1.0f};
- const int maxpixel = (ibuf->x * ibuf->y) - 1;
+ // const int maxpixel = (ibuf->x * ibuf->y) - 1;
/* detect pixels and expand into red areas */
- for (int v = maxpixel; v != 0; v--) {
- float color[4];
- int index;
- int tp = 0;
- int bm = 0;
- int lt = 0;
- int rt = 0;
- get_pixel(ibuf, v, color);
- if (color[1] == 1.0f) {
- /* pixel left */
- if (v - 1 >= 0) {
- index = v - 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
- lt = index;
+ for (int row = 0; row < ibuf->y; row++) {
+ if (!is_row_filled(ibuf, row)) {
+ continue;
+ }
+ int maxpixel = (ibuf->x * (row + 1)) - 1;
+ int minpixel = ibuf->x * row;
+
+ for (int v = maxpixel; v != minpixel; v--) {
+ float color[4];
+ int index;
+ get_pixel(ibuf, v, color);
+ if (color[1] == 1.0f) {
+ int tp = 0;
+ int bm = 0;
+ int lt = 0;
+ int rt = 0;
+
+ /* pixel left */
+ if (v - 1 >= 0) {
+ index = v - 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ lt = index;
+ }
}
- }
- /* pixel right */
- if (v + 1 <= maxpixel) {
- index = v + 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
- rt = index;
+ /* pixel right */
+ if (v + 1 <= maxpixel) {
+ index = v + 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ rt = index;
+ }
}
- }
- /* pixel top */
- if (v + ibuf->x <= maxpixel) {
- index = v + ibuf->x;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
- tp = index;
+ /* pixel top */
+ if (v + (ibuf->x * 1) <= maxpixel) {
+ index = v + (ibuf->x * 1);
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ tp = index;
+ }
}
- }
- /* pixel bottom */
- if (v - ibuf->x >= 0) {
- index = v - ibuf->x;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
- bm = index;
+ /* pixel bottom */
+ if (v - (ibuf->x * 1) >= 0) {
+ index = v - (ibuf->x * 1);
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ bm = index;
+ }
}
- }
- /* pixel top-left */
- if (tp && lt) {
- index = tp - 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
+ /* pixel top-left */
+ if (tp && lt) {
+ index = tp - 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ }
}
- }
- /* pixel top-right */
- if (tp && rt) {
- index = tp + 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
+ /* pixel top-right */
+ if (tp && rt) {
+ index = tp + 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ }
}
- }
- /* pixel bottom-left */
- if (bm && lt) {
- index = bm - 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
+ /* pixel bottom-left */
+ if (bm && lt) {
+ index = bm - 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ }
}
- }
- /* pixel bottom-right */
- if (bm && rt) {
- index = bm + 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
+ /* pixel bottom-right */
+ if (bm && rt) {
+ index = bm + 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ }
}
}
}
@@ -946,8 +1210,11 @@ static void dilate_shape(ImBuf *ibuf)
int v;
BLI_stack_pop(stack, &v);
set_pixel(ibuf, v, green);
+ done = true;
}
BLI_stack_free(stack);
+
+ return done;
}
/* Get the outline points of a shape using Moore Neighborhood algorithm
@@ -963,11 +1230,12 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
int v[2];
int boundary_co[2];
int start_co[2];
+ int first_co[2] = {-1, -1};
int backtracked_co[2];
int current_check_co[2];
int prev_check_co[2];
int backtracked_offset[1][2] = {{0, 0}};
- // bool boundary_found = false;
+ bool first_pixel = false;
bool start_found = false;
const int NEIGHBOR_COUNT = 8;
@@ -992,7 +1260,6 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
dilate_shape(ibuf);
}
- /* find the initial point to start outline analysis */
for (int idx = imagesize - 1; idx != 0; idx--) {
get_pixel(ibuf, idx, rgba);
if (rgba[1] == 1.0f) {
@@ -1015,7 +1282,7 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
int cur_back_offset = -1;
for (int i = 0; i < NEIGHBOR_COUNT; i++) {
if (backtracked_offset[0][0] == offset[i][0] && backtracked_offset[0][1] == offset[i][1]) {
- /* Finding the bracktracked pixel offset index */
+ /* Finding the back-tracked pixel offset index */
cur_back_offset = i;
break;
}
@@ -1045,19 +1312,24 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
cur_back_offset++;
loop++;
}
- /* current pixel is equal to starting pixel */
- if (boundary_co[0] == start_co[0] && boundary_co[1] == start_co[1]) {
+ /* Current pixel is equal to starting or first pixel. */
+ if ((boundary_co[0] == start_co[0] && boundary_co[1] == start_co[1]) ||
+ (boundary_co[0] == first_co[0] && boundary_co[1] == first_co[1])) {
BLI_stack_pop(tgpf->stack, &v);
- // boundary_found = true;
break;
}
+
+ if (!first_pixel) {
+ first_pixel = true;
+ copy_v2_v2_int(first_co, boundary_co);
+ }
}
/* release ibuf */
BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
}
-/* get z-depth array to reproject on surface */
+/* Get z-depth array to reproject on surface. */
static void gpencil_get_depth_array(tGPDfill *tgpf)
{
tGPspoint *ptc;
@@ -1108,7 +1380,7 @@ static void gpencil_get_depth_array(tGPDfill *tgpf)
}
if (found_depth == false) {
- /* eeh... not much we can do.. :/, ignore depth in this case */
+ /* Sigh! not much we can do here. Ignore depth in this case. */
for (i = totpoints - 1; i >= 0; i--) {
tgpf->depth_arr[i] = 0.9999f;
}
@@ -1171,6 +1443,9 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
return;
}
+ /* Set as done. */
+ tgpf->done = true;
+
/* Get frame or create a new one. */
tgpf->gpf = BKE_gpencil_layer_frame_get(tgpf->gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW);
@@ -1275,7 +1550,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
float origin[3];
ED_gpencil_drawing_reference_get(tgpf->scene, tgpf->ob, ts->gpencil_v3d_align, origin);
ED_gpencil_project_stroke_to_plane(
- tgpf->scene, tgpf->ob, tgpf->rv3d, gps, origin, tgpf->lock_axis - 1);
+ tgpf->scene, tgpf->ob, tgpf->rv3d, tgpf->gpl, gps, origin, tgpf->lock_axis - 1);
}
/* if parented change position relative to parent object */
@@ -1326,7 +1601,6 @@ static void gpencil_fill_draw_3d(const bContext *C, ARegion *UNUSED(region), voi
if (region != tgpf->region) {
return;
}
-
gpencil_draw_boundary_lines(C, tgpf);
}
@@ -1377,6 +1651,10 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
tgpf->win = CTX_wm_window(C);
tgpf->active_cfra = CFRA;
+ /* Setup space conversions. */
+ gpencil_point_conversion_init(C, &tgpf->gsc);
+ tgpf->zoom = 1.0f;
+
/* set GP datablock */
tgpf->gpd = gpd;
tgpf->gpl = BKE_gpencil_layer_active_get(gpd);
@@ -1387,6 +1665,7 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
tgpf->lock_axis = ts->gp_sculpt.lock_axis;
tgpf->oldkey = -1;
+ tgpf->is_render = false;
tgpf->sbuffer_used = 0;
tgpf->sbuffer = NULL;
tgpf->depth_arr = NULL;
@@ -1395,11 +1674,13 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
tgpf->brush = brush;
tgpf->flag = brush->gpencil_settings->flag;
- tgpf->fill_leak = brush->gpencil_settings->fill_leak;
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_factor = (short)max_ii(1, min_ii((int)brush->gpencil_settings->fill_factor, 8));
+ 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);
int totcol = tgpf->ob->totcol;
@@ -1424,7 +1705,6 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
/* end operator */
static void gpencil_fill_exit(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_active_object(C);
/* clear undo stack */
@@ -1443,16 +1723,14 @@ static void gpencil_fill_exit(bContext *C, wmOperator *op)
MEM_SAFE_FREE(tgpf->sbuffer);
MEM_SAFE_FREE(tgpf->depth_arr);
+ /* Remove any temp stroke. */
+ gpencil_delete_temp_stroke_extension(tgpf, true);
+
/* remove drawing handler */
if (tgpf->draw_handle_3d) {
ED_region_draw_cb_exit(tgpf->region->type, tgpf->draw_handle_3d);
}
- /* Delete temp image. */
- if (tgpf->ima) {
- BKE_id_free(bmain, tgpf->ima);
- }
-
/* finally, free memory used by temp data */
MEM_freeN(tgpf);
}
@@ -1536,7 +1814,11 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
tgpf = op->customdata;
/* Enable custom drawing handlers to show help lines */
- if (tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) {
+ 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)));
+
+ if (help_lines) {
tgpf->draw_handle_3d = ED_region_draw_cb_activate(
tgpf->region->type, gpencil_fill_draw_3d, tgpf, REGION_DRAW_POST_VIEW);
}
@@ -1554,17 +1836,210 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
return OPERATOR_RUNNING_MODAL;
}
+/* Helper: Calc the maximum bounding box size of strokes to get the zoom level of the viewport.
+ * For each stroke, the 2D projected bounding box is calculated and using this data, the total
+ * object bounding box (all strokes) is calculated. */
+static void gpencil_zoom_level_set(tGPDfill *tgpf)
+{
+ Brush *brush = tgpf->brush;
+ if (brush->gpencil_settings->flag & GP_BRUSH_FILL_FIT_DISABLE) {
+ tgpf->zoom = 1.0f;
+ return;
+ }
+
+ Object *ob = tgpf->ob;
+ bGPdata *gpd = tgpf->gpd;
+ BrushGpencilSettings *brush_settings = tgpf->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);
+
+ /* Init maximum boundbox size. */
+ rctf rect_max;
+ const float winx_half = tgpf->region->winx / 2.0f;
+ const float winy_half = tgpf->region->winy / 2.0f;
+ BLI_rctf_init(&rect_max,
+ 0.0f - winx_half,
+ tgpf->region->winx + winx_half,
+ 0.0f - winy_half,
+ tgpf->region->winy + winy_half);
+
+ float objectbox_min[2], objectbox_max[2];
+ INIT_MINMAX2(objectbox_min, objectbox_max);
+ rctf rect_bound;
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+ float diff_mat[4][4];
+ /* calculate parent matrix */
+ BKE_gpencil_layer_transform_matrix_get(tgpf->depsgraph, ob, gpl, diff_mat);
+
+ /* Decide if the strokes of layers are included or not depending on the layer mode.
+ * Cannot skip the layer because it can use boundary strokes and must be used. */
+ const int gpl_index = BLI_findindex(&gpd->layers, gpl);
+ bool skip = skip_layer_check(brush_settings->fill_layer_mode, gpl_active_index, gpl_index);
+
+ /* Get frame to check. */
+ bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, tgpf->active_cfra, GP_GETFRAME_USE_PREV);
+ if (gpf == NULL) {
+ continue;
+ }
+
+ /* Read all strokes. */
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* check if stroke can be drawn */
+ if ((gps->points == NULL) || (gps->totpoints < 2)) {
+ 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;
+ }
+
+ /* If the layer must be skipped, but the stroke is not boundary, skip stroke. */
+ if ((skip) && ((gps->flag & GP_STROKE_NOFILL) == 0)) {
+ continue;
+ }
+
+ float boundbox_min[2];
+ float boundbox_max[2];
+ ED_gpencil_projected_2d_bound_box(&tgpf->gsc, gps, diff_mat, boundbox_min, boundbox_max);
+ minmax_v2v2_v2(objectbox_min, objectbox_max, boundbox_min);
+ minmax_v2v2_v2(objectbox_min, objectbox_max, boundbox_max);
+ }
+ }
+ /* Clamp max bound box. */
+ BLI_rctf_init(
+ &rect_bound, objectbox_min[0], objectbox_max[0], objectbox_min[1], objectbox_max[1]);
+ float r_xy[2];
+ BLI_rctf_clamp(&rect_bound, &rect_max, r_xy);
+
+ /* Calculate total width used. */
+ float width = tgpf->region->winx;
+ if (rect_bound.xmin < 0.0f) {
+ width -= rect_bound.xmin;
+ }
+ if (rect_bound.xmax > tgpf->region->winx) {
+ width += rect_bound.xmax - tgpf->region->winx;
+ }
+ /* Calculate total height used. */
+ float height = tgpf->region->winy;
+ if (rect_bound.ymin < 0.0f) {
+ height -= rect_bound.ymin;
+ }
+ if (rect_bound.ymax > tgpf->region->winy) {
+ height += rect_bound.ymax - tgpf->region->winy;
+ }
+
+ width = ceilf(width);
+ height = ceilf(height);
+
+ float zoomx = (width > tgpf->region->winx) ? width / (float)tgpf->region->winx : 1.0f;
+ float zoomy = (height > tgpf->region->winy) ? height / (float)tgpf->region->winy : 1.0f;
+ if ((zoomx != 1.0f) || (zoomy != 1.0f)) {
+ tgpf->zoom = min_ff(max_ff(zoomx, zoomy) * 1.5f, 5.0f);
+ }
+}
+
+static bool gpencil_do_frame_fill(tGPDfill *tgpf, const bool is_inverted)
+{
+ wmWindow *win = CTX_wm_window(tgpf->C);
+
+ /* render screen to temp image */
+ int totpoints = 1;
+ if (gpencil_render_offscreen(tgpf)) {
+
+ /* Set red borders to create a external limit. */
+ gpencil_set_borders(tgpf, true);
+
+ /* apply boundary fill */
+ gpencil_boundaryfill_area(tgpf);
+
+ /* Invert direction if press Ctrl. */
+ if (is_inverted) {
+ gpencil_invert_image(tgpf);
+ }
+
+ /* Clean borders to avoid infinite loops. */
+ gpencil_set_borders(tgpf, false);
+ WM_cursor_time(win, 50);
+ int totpoints_prv = 0;
+ int loop_limit = 0;
+ while (totpoints > 0) {
+ /* analyze outline */
+ gpencil_get_outline_points(tgpf, (totpoints == 1) ? true : false);
+
+ /* create array of points from stack */
+ totpoints = gpencil_points_from_stack(tgpf);
+
+ /* create z-depth array for reproject */
+ gpencil_get_depth_array(tgpf);
+
+ /* create stroke and reproject */
+ gpencil_stroke_from_buffer(tgpf);
+
+ if (is_inverted) {
+ gpencil_erase_processed_area(tgpf);
+ }
+ else {
+ /* Exit of the loop. */
+ totpoints = 0;
+ }
+
+ /* free temp stack data */
+ if (tgpf->stack) {
+ BLI_stack_free(tgpf->stack);
+ }
+ WM_cursor_time(win, 100);
+
+ /* Free memory. */
+ MEM_SAFE_FREE(tgpf->sbuffer);
+ MEM_SAFE_FREE(tgpf->depth_arr);
+
+ /* Limit very small areas. */
+ if (totpoints < 3) {
+ break;
+ }
+ /* Limit infinite loops is some corner cases. */
+ if (totpoints_prv == totpoints) {
+ loop_limit++;
+ if (loop_limit > 3) {
+ break;
+ }
+ }
+ totpoints_prv = totpoints;
+ }
+
+ /* Delete temp image. */
+ if ((tgpf->ima) && (!FILL_DEBUG)) {
+ BKE_id_free(tgpf->bmain, tgpf->ima);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
/* events handling during interactive part of operator */
static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPDfill *tgpf = op->customdata;
- Scene *scene = tgpf->scene;
Brush *brush = tgpf->brush;
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
+ tgpf->on_back = RNA_boolean_get(op->ptr, "on_back");
+
const bool is_brush_inv = brush_settings->fill_direction == BRUSH_DIR_IN;
const bool is_inverted = (is_brush_inv && !event->ctrl) || (!is_brush_inv && event->ctrl);
-
- int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through */
+ 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)));
+ int estate = OPERATOR_RUNNING_MODAL;
switch (event->type) {
case EVT_ESCKEY:
@@ -1572,82 +2047,104 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_CANCELLED;
break;
case LEFTMOUSE:
- tgpf->on_back = RNA_boolean_get(op->ptr, "on_back");
/* first time the event is not enabled to show help lines. */
- if ((tgpf->oldkey != -1) || ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) == 0)) {
+ if ((tgpf->oldkey != -1) || (!help_lines)) {
ARegion *region = BKE_area_find_region_xy(
CTX_wm_area(C), RGN_TYPE_ANY, event->x, event->y);
if (region) {
bool in_bounds = false;
-
/* Perform bounds check */
in_bounds = BLI_rcti_isect_pt(&region->winrct, event->x, event->y);
if ((in_bounds) && (region->regiontype == RGN_TYPE_WINDOW)) {
- tgpf->center[0] = event->mval[0];
- tgpf->center[1] = event->mval[1];
-
- /* Set active frame as current for filling. */
- tgpf->active_cfra = CFRA;
+ tgpf->mouse[0] = event->mval[0];
+ tgpf->mouse[1] = event->mval[1];
+ tgpf->is_render = true;
+ /* Define Zoom level. */
+ gpencil_zoom_level_set(tgpf);
+
+ /* Create Temp stroke. */
+ tgpf->gps_mouse = BKE_gpencil_stroke_new(0, 1, 10.0f);
+ tGPspoint point2D;
+ bGPDspoint *pt = &tgpf->gps_mouse->points[0];
+ copy_v2fl_v2i(&point2D.x, tgpf->mouse);
+ gpencil_stroke_convertcoords_tpoint(
+ tgpf->scene, tgpf->region, tgpf->ob, &point2D, NULL, &pt->x);
+
+ /* If not multiframe and there is no frame in CFRA for the active layer, create
+ * a new frame before to make the hash function can find something. */
+ if (!is_multiedit) {
+ tgpf->gpf = BKE_gpencil_layer_frame_get(
+ tgpf->gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW);
+ tgpf->gpf->flag |= GP_FRAME_SELECT;
+ }
- /* render screen to temp image */
- int totpoints = 1;
- if (gpencil_render_offscreen(tgpf)) {
+ /* Hash of selected frames.*/
+ GHash *frame_list = BLI_ghash_int_new_ex(__func__, 64);
+ BKE_gpencil_frame_selected_hash(tgpf->gpd, frame_list);
- /* Set red borders to create a external limit. */
- gpencil_set_borders(tgpf, true);
+ /* Loop all frames. */
+ wmWindow *win = CTX_wm_window(C);
- /* apply boundary fill */
- gpencil_boundaryfill_area(tgpf);
+ GHashIterator gh_iter;
+ int total = BLI_ghash_len(frame_list);
+ int i = 1;
+ GHASH_ITER (gh_iter, frame_list) {
+ /* Set active frame as current for filling. */
+ tgpf->active_cfra = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
+ int step = ((float)i / (float)total) * 100.0f;
+ WM_cursor_time(win, step);
- /* Invert direction if press Ctrl. */
- if (is_inverted) {
- gpencil_invert_image(tgpf);
+ if (do_extend) {
+ gpencil_update_extend(tgpf);
}
- /* Clean borders to avoid infinite loops. */
- gpencil_set_borders(tgpf, false);
-
- while (totpoints > 0) {
- /* analyze outline */
- gpencil_get_outline_points(tgpf, (totpoints == 1) ? true : false);
-
- /* create array of points from stack */
- totpoints = gpencil_points_from_stack(tgpf);
-
- /* create z-depth array for reproject */
- gpencil_get_depth_array(tgpf);
-
- /* create stroke and reproject */
- gpencil_stroke_from_buffer(tgpf);
-
- if (is_inverted) {
- gpencil_erase_processed_area(tgpf);
- }
- else {
- /* Exit of the loop. */
- totpoints = 0;
- }
-
- /* free temp stack data */
- if (tgpf->stack) {
- BLI_stack_free(tgpf->stack);
+ /* Repeat loop until get something. */
+ tgpf->done = false;
+ int loop_limit = 0;
+ while ((!tgpf->done) && (loop_limit < 2)) {
+ WM_cursor_time(win, loop_limit + 1);
+ /* Render screen to temp image and do fill. */
+ gpencil_do_frame_fill(tgpf, is_inverted);
+
+ /* restore size */
+ tgpf->region->winx = (short)tgpf->bwinx;
+ tgpf->region->winy = (short)tgpf->bwiny;
+ tgpf->region->winrct = tgpf->brect;
+ if (!tgpf->done) {
+ /* If the zoom was not set before, avoid a loop. */
+ if (tgpf->zoom == 1.0f) {
+ loop_limit++;
+ }
+ else {
+ tgpf->zoom = 1.0f;
+ tgpf->fill_factor = max_ff(
+ GPENCIL_MIN_FILL_FAC,
+ min_ff(brush->gpencil_settings->fill_factor, GPENCIL_MAX_FILL_FAC));
+ }
}
+ loop_limit++;
+ }
- /* Free memory. */
- MEM_SAFE_FREE(tgpf->sbuffer);
- MEM_SAFE_FREE(tgpf->depth_arr);
+ if (do_extend) {
+ gpencil_delete_temp_stroke_extension(tgpf, true);
}
+
+ i++;
}
+ WM_cursor_modal_restore(win);
+ /* Free hash table. */
+ BLI_ghash_free(frame_list, NULL, NULL);
- /* restore size */
- tgpf->region->winx = (short)tgpf->bwinx;
- tgpf->region->winy = (short)tgpf->bwiny;
- tgpf->region->winrct = tgpf->brect;
+ /* Free temp stroke. */
+ BKE_gpencil_free_stroke(tgpf->gps_mouse);
/* push undo data */
gpencil_undo_push(tgpf->gpd);
+ /* Save extend value for next operation. */
+ brush_settings->fill_extend_fac = tgpf->fill_extend_fac;
+
estate = OPERATOR_FINISHED;
}
else {
@@ -1658,8 +2155,29 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_CANCELLED;
}
}
+ else if (do_extend) {
+ gpencil_update_extend(tgpf);
+ }
tgpf->oldkey = event->type;
break;
+ case EVT_PAGEUPKEY:
+ case WHEELUPMOUSE:
+ if (tgpf->oldkey == 1) {
+ tgpf->fill_extend_fac -= (event->shift) ? 0.01f : 0.1f;
+ CLAMP_MIN(tgpf->fill_extend_fac, 0.0f);
+ gpencil_update_extend(tgpf);
+ }
+ break;
+ case EVT_PAGEDOWNKEY:
+ case WHEELDOWNMOUSE:
+ if (tgpf->oldkey == 1) {
+ tgpf->fill_extend_fac += (event->shift) ? 0.01f : 0.1f;
+ CLAMP_MAX(tgpf->fill_extend_fac, 100.0f);
+ gpencil_update_extend(tgpf);
+ }
+ break;
+ default:
+ break;
}
/* process last operations before exiting */
switch (estate) {
@@ -1672,7 +2190,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
gpencil_fill_exit(C, op);
break;
- case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH:
+ default:
break;
}
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 4a908eff92e..5fea46626d5 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -667,7 +667,8 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
/* loop over strokes */ \
bGPDstroke *gpsn_; \
@@ -678,7 +679,7 @@ struct GP_EditableStrokes_Iter {
continue; \
} \
/* check if the color is editable */ \
- if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) { \
+ if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
continue; \
} \
/* ... Do Stuff With Strokes ... */
@@ -718,7 +719,8 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
/* loop over strokes */ \
bGPDstroke *gpsn_; \
@@ -767,8 +769,10 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
- invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ /* Undo layer transform. */ \
+ mul_m4_m4m4(gpstroke_iter.diff_mat, gpstroke_iter.diff_mat, gpl->layer_invmat); \
/* loop over strokes */ \
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf_->strokes) { \
/* skip strokes that are invalid for current view */ \
@@ -776,7 +780,7 @@ struct GP_EditableStrokes_Iter {
continue; \
} \
/* check if the color is editable */ \
- if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) { \
+ if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
continue; \
} \
/* ... Do Stuff With Strokes ... */
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index c666fcb67b7..ecd243ed595 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -48,31 +48,22 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_deform.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
#include "BKE_report.h"
#include "UI_interface.h"
-#include "UI_resources.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "UI_view2d.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_space_api.h"
-#include "ED_view3d.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
@@ -229,7 +220,7 @@ static bool gpencil_interpolate_check_todo(bContext *C, bGPdata *gpd)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps_from) == false) {
continue;
}
@@ -283,8 +274,8 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
tgpil = MEM_callocN(sizeof(tGPDinterpolate_layer), "GPencil Interpolate Layer");
tgpil->gpl = gpl;
- tgpil->prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe);
- tgpil->nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next);
+ tgpil->prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe, true);
+ tgpil->nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next, true);
BLI_addtail(&tgpi->ilayers, tgpil);
@@ -315,7 +306,7 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, tgpil->gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, tgpil->gpl, gps_from) == false) {
valid = false;
}
@@ -734,7 +725,7 @@ void GPENCIL_OT_interpolate(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
/* properties */
- RNA_def_float_percentage(
+ RNA_def_float_factor(
ot->srna,
"shift",
0.0f,
@@ -1008,8 +999,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
}
/* store extremes */
- prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe);
- nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next);
+ prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe, true);
+ nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next, true);
/* Loop over intermediary frames and create the interpolation */
for (cframe = prevFrame->framenum + step; cframe < nextFrame->framenum; cframe += step) {
@@ -1048,7 +1039,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps_from) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c
index 272dff56291..435bff34998 100644
--- a/source/blender/editors/gpencil/gpencil_merge.c
+++ b/source/blender/editors/gpencil/gpencil_merge.c
@@ -48,12 +48,9 @@
#include "RNA_define.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_view3d.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index 53beaeaa6a0..ffe676f0520 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -36,8 +36,6 @@
#include "BKE_anim_data.h"
#include "BKE_context.h"
#include "BKE_duplilist.h"
-#include "BKE_global.h"
-#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
#include "BKE_layer.h"
#include "BKE_main.h"
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 0a29b83bc4f..1a6cb5670c4 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -27,9 +27,7 @@
#include "BLI_sys_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_gpencil.h"
#include "BKE_paint.h"
#include "DNA_brush_types.h"
@@ -45,9 +43,6 @@
#include "RNA_access.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
-#include "ED_select_utils.h"
-#include "ED_transform.h"
#include "gpencil_intern.h"
diff --git a/source/blender/editors/gpencil/gpencil_ops_versioning.c b/source/blender/editors/gpencil/gpencil_ops_versioning.c
index 815bbbaa254..45842c28dff 100644
--- a/source/blender/editors/gpencil/gpencil_ops_versioning.c
+++ b/source/blender/editors/gpencil/gpencil_ops_versioning.c
@@ -34,16 +34,12 @@
#include "DNA_gpencil_types.h"
#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_deform.h"
#include "BKE_gpencil.h"
#include "BKE_main.h"
-#include "BKE_material.h"
#include "BKE_object.h"
#include "WM_api.h"
@@ -53,7 +49,6 @@
#include "RNA_define.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index ed56f004ca4..b833125cf34 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -426,7 +426,7 @@ static void gpencil_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
/* get drawing origin */
gpencil_get_3d_reference(p, origin);
- ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, gps, origin, p->lock_axis - 1);
+ ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, p->gpl, gps, origin, p->lock_axis - 1);
}
/* convert screen-coordinates to buffer-coordinates */
@@ -887,11 +887,13 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
gpencil_get_3d_reference(p, origin);
/* reproject current */
ED_gpencil_tpoint_to_point(p->region, origin, pt, &spt);
- ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt);
+ ED_gpencil_project_point_to_plane(
+ p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt);
/* reproject previous */
ED_gpencil_tpoint_to_point(p->region, origin, ptb, &spt2);
- ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt2);
+ ED_gpencil_project_point_to_plane(
+ p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt2);
p->totpixlen += len_v3v3(&spt.x, &spt2.x);
pt->uv_fac = p->totpixlen;
}
@@ -1304,6 +1306,12 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gpd, gps);
+ /* In Multiframe mode, duplicate the stroke in other frames. */
+ if (GPENCIL_MULTIEDIT_SESSIONS_ON(p->gpd)) {
+ const bool tail = (ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK);
+ BKE_gpencil_stroke_copy_to_keyframes(gpd, gpl, p->gpf, gps, tail);
+ }
+
gpencil_stroke_added_enable(p);
}
@@ -1321,10 +1329,8 @@ static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
}
/* only erase stroke points that are visible */
-static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
- const bGPDspoint *pt,
- const int x,
- const int y)
+static bool gpencil_stroke_eraser_is_occluded(
+ tGPsdata *p, bGPDlayer *gpl, const bGPDspoint *pt, const int x, const int y)
{
Object *obact = (Object *)p->ownerPtr.data;
Brush *brush = p->brush;
@@ -1341,7 +1347,6 @@ static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
if ((gp_settings != NULL) && (p->area->spacetype == SPACE_VIEW3D) &&
(gp_settings->flag & GP_BRUSH_OCCLUDE_ERASER)) {
RegionView3D *rv3d = p->region->regiondata;
- bGPDlayer *gpl = p->gpl;
const int mval_i[2] = {x, y};
float mval_3d[3];
@@ -1349,7 +1354,7 @@ static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
float diff_mat[4][4];
/* calculate difference matrix if parent object */
- BKE_gpencil_parent_matrix_get(p->depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(p->depsgraph, obact, gpl, diff_mat);
if (ED_view3d_autodist_simple(p->region, mval_i, mval_3d, 0, NULL)) {
const float depth_mval = view3d_point_depth(rv3d, mval_3d);
@@ -1452,6 +1457,7 @@ static void gpencil_stroke_soft_refine(bGPDstroke *gps)
/* eraser tool - evaluation per stroke */
static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
+ bGPDlayer *gpl,
bGPDframe *gpf,
bGPDstroke *gps,
const float mval[2],
@@ -1577,9 +1583,9 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
* - this assumes that linewidth is irrelevant
*/
if (gpencil_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
- if ((gpencil_stroke_eraser_is_occluded(p, pt0, pc0[0], pc0[1]) == false) ||
- (gpencil_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
- (gpencil_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) {
+ if ((gpencil_stroke_eraser_is_occluded(p, gpl, pt0, pc0[0], pc0[1]) == false) ||
+ (gpencil_stroke_eraser_is_occluded(p, gpl, pt1, pc1[0], pc1[1]) == false) ||
+ (gpencil_stroke_eraser_is_occluded(p, gpl, pt2, pc2[0], pc2[1]) == false)) {
/* Point is affected: */
/* Adjust thickness
* - Influence of eraser falls off with distance from the middle of the eraser
@@ -1681,6 +1687,8 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
/* erase strokes which fall under the eraser strokes */
static void gpencil_stroke_doeraser(tGPsdata *p)
{
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(p->gpd);
+
rcti rect;
Brush *brush = p->brush;
Brush *eraser = p->eraser;
@@ -1721,40 +1729,53 @@ static void gpencil_stroke_doeraser(tGPsdata *p)
* on multiple layers...
*/
LISTBASE_FOREACH (bGPDlayer *, gpl, &p->gpd->layers) {
- bGPDframe *gpf = gpl->actframe;
-
/* only affect layer if it's editable (and visible) */
if (BKE_gpencil_layer_is_editable(gpl) == false) {
continue;
}
- if (gpf == NULL) {
+
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+ if (init_gpf == NULL) {
continue;
}
- /* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
- /* loop over strokes, checking segments for intersections */
- LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(p->ob, gpl, gps) == false) {
- continue;
- }
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
+ }
+ /* calculate difference matrix */
+ BKE_gpencil_layer_transform_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
+
+ /* loop over strokes, checking segments for intersections */
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_material_editable(p->ob, gpl, gps) == false) {
+ continue;
+ }
- /* Check if the stroke collide with mouse. */
- if (!ED_gpencil_stroke_check_collision(&p->gsc, gps, p->mval, calc_radius, p->diff_mat)) {
- continue;
- }
+ /* Check if the stroke collide with mouse. */
+ if (!ED_gpencil_stroke_check_collision(
+ &p->gsc, gps, p->mval, calc_radius, p->diff_mat)) {
+ continue;
+ }
- /* Not all strokes in the datablock may be valid in the current editor/context
- * (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
- */
- if (ED_gpencil_stroke_can_use_direct(p->area, gps)) {
- gpencil_stroke_eraser_dostroke(p, gpf, gps, p->mval, calc_radius, &rect);
+ /* Not all strokes in the datablock may be valid in the current editor/context
+ * (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
+ */
+ if (ED_gpencil_stroke_can_use_direct(p->area, gps)) {
+ gpencil_stroke_eraser_dostroke(p, gpl, gpf, gps, p->mval, calc_radius, &rect);
+ }
+ }
+
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
}
}
}
}
-
/* ******************************************* */
/* Sketching Operator */
@@ -2103,6 +2124,11 @@ static void gpencil_paint_initstroke(tGPsdata *p,
copy_v3_v3(p->gpl->color, p->custom_color);
}
}
+
+ /* Recalculate layer transform matrix to avoid problems if props are animated. */
+ loc_eul_size_to_mat4(p->gpl->layer_mat, p->gpl->location, p->gpl->rotation, p->gpl->scale);
+ invert_m4_m4(p->gpl->layer_invmat, p->gpl->layer_mat);
+
if ((paintmode != GP_PAINTMODE_ERASER) && (p->gpl->flag & GP_LAYER_LOCKED)) {
p->status = GP_STATUS_ERROR;
if (G.debug & G_DEBUG) {
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 53e0043df37..bcdde49b93d 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -317,6 +317,10 @@ static void gpencil_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
}
tgpi->gpl = gpl;
+ /* Recalculate layer transform matrix to avoid problems if props are animated. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
/* create a new temporary frame */
tgpi->gpf = MEM_callocN(sizeof(bGPDframe), "Temp bGPDframe");
tgpi->gpf->framenum = tgpi->cframe = cfra;
@@ -1004,12 +1008,12 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
/* reproject current */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tpt, &spt);
ED_gpencil_project_point_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
+ tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
/* reproject previous */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tptb, &spt2);
ED_gpencil_project_point_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
+ tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
tgpi->totpixlen += len_v3v3(&spt.x, &spt2.x);
tpt->uv_fac = tgpi->totpixlen;
}
@@ -1068,7 +1072,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
float origin[3];
ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
ED_gpencil_project_stroke_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, gps, origin, ts->gp_sculpt.lock_axis - 1);
+ tgpi->scene, tgpi->ob, tgpi->rv3d, tgpi->gpl, gps, origin, ts->gp_sculpt.lock_axis - 1);
}
/* if parented change position relative to parent object */
@@ -1373,6 +1377,12 @@ static void gpencil_primitive_interaction_end(bContext *C,
BKE_gpencil_stroke_geometry_update(tgpi->gpd, gps);
}
+ /* In Multiframe mode, duplicate the stroke in other frames. */
+ if (GPENCIL_MULTIEDIT_SESSIONS_ON(tgpi->gpd)) {
+ const bool tail = (ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK);
+ BKE_gpencil_stroke_copy_to_keyframes(tgpi->gpd, tgpi->gpl, gpf, gps, tail);
+ }
+
DEG_id_tag_update(&tgpi->gpd->id, ID_RECALC_COPY_ON_WRITE);
DEG_id_tag_update(&tgpi->gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index bb9dd8cac5d..0d3ab9011d6 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -1441,11 +1441,6 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
bool changed = false;
float rot_eval = 0.0f;
- /* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
- return false;
- }
-
if (gps->totpoints == 1) {
bGPDspoint pt_temp;
pt = &gps->points[0];
@@ -1577,6 +1572,13 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
Object *ob = gso->object;
bGPdata *gpd = ob->data;
char tool = gso->brush->gpencil_sculpt_tool;
+ GP_SpaceConversion *gsc = &gso->gsc;
+ Brush *brush = gso->brush;
+ const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure :
+ gso->brush->size;
+ /* Calc bound box matrix. */
+ float bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* skip strokes that are invalid for current view */
@@ -1584,7 +1586,12 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, 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;
}
@@ -1742,7 +1749,8 @@ static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *
/* calculate difference matrix */
float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 281ab8c5adc..a00d21bf88a 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -2473,7 +2473,7 @@ static void gpencil_selected_hue_table(bContext *C,
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
if ((gps->flag & GP_STROKE_SELECT) == 0) {
diff --git a/source/blender/editors/gpencil/gpencil_trace_ops.c b/source/blender/editors/gpencil/gpencil_trace_ops.c
index 0be9d74278e..0f344909692 100644
--- a/source/blender/editors/gpencil/gpencil_trace_ops.c
+++ b/source/blender/editors/gpencil/gpencil_trace_ops.c
@@ -23,7 +23,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLT_translation.h"
@@ -31,34 +30,26 @@
#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
#include "BKE_context.h"
-#include "BKE_duplilist.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
-#include "BKE_material.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
-
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
-#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "ED_gpencil.h"
@@ -66,7 +57,6 @@
#include "gpencil_intern.h"
#include "gpencil_trace.h"
-#include "potracelib.h"
typedef struct TraceJob {
/* from wmJob */
@@ -87,6 +77,7 @@ typedef struct TraceJob {
bGPDlayer *gpl;
bool was_ob_created;
+ bool use_current_frame;
int32_t frame_target;
float threshold;
@@ -228,15 +219,17 @@ static void trace_start_job(void *customdata, short *stop, short *do_update, flo
trace_job->do_update = do_update;
trace_job->progress = progress;
trace_job->was_canceled = false;
+ const int init_frame = max_ii((trace_job->use_current_frame) ? trace_job->frame_target : 0, 0);
G.is_break = false;
/* Single Image. */
-
if ((trace_job->image->source == IMA_SRC_FILE) ||
(trace_job->mode == GPENCIL_TRACE_MODE_SINGLE)) {
void *lock;
- ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, NULL, &lock);
+ ImageUser *iuser = trace_job->ob_active->iuser;
+ iuser->framenr = init_frame;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, iuser, &lock);
if (ibuf) {
/* Create frame. */
bGPDframe *gpf = BKE_gpencil_layer_frame_get(
@@ -249,7 +242,7 @@ static void trace_start_job(void *customdata, short *stop, short *do_update, flo
/* Image sequence. */
else if (trace_job->image->type == IMA_TYPE_IMAGE) {
ImageUser *iuser = trace_job->ob_active->iuser;
- for (int i = 0; i < iuser->frames; i++) {
+ for (int i = init_frame; i < iuser->frames; i++) {
if (G.is_break) {
trace_job->was_canceled = true;
break;
@@ -320,6 +313,7 @@ static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
job->ob_active = job->base_active->object;
job->image = (Image *)job->ob_active->data;
job->frame_target = CFRA;
+ job->use_current_frame = RNA_boolean_get(op->ptr, "use_current_frame");
/* Create a new grease pencil object or reuse selected. */
eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target");
@@ -493,4 +487,9 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
GPENCIL_TRACE_MODE_SINGLE,
"Mode",
"Determines if trace simple image or full sequence");
+ RNA_def_boolean(ot->srna,
+ "use_current_frame",
+ true,
+ "Start At Current Frame",
+ "Trace Image starting in current image frame");
}
diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c
index c2504ce329e..4e172104ce7 100644
--- a/source/blender/editors/gpencil/gpencil_undo.c
+++ b/source/blender/editors/gpencil/gpencil_undo.c
@@ -36,6 +36,7 @@
#include "BKE_blender_undo.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
+#include "BKE_undo_system.h"
#include "ED_gpencil.h"
@@ -61,28 +62,22 @@ int ED_gpencil_session_active(void)
return (BLI_listbase_is_empty(&undo_nodes) == false);
}
-int ED_undo_gpencil_step(bContext *C, int step, const char *name)
+int ED_undo_gpencil_step(bContext *C, const eUndoStepDir step)
{
bGPdata **gpd_ptr = NULL, *new_gpd = NULL;
gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
- if (step == 1) { /* undo */
- // printf("\t\tGP - undo step\n");
+ if (step == STEP_UNDO) {
if (cur_node->prev) {
- if (!name || STREQ(cur_node->name, name)) {
- cur_node = cur_node->prev;
- new_gpd = cur_node->gpd;
- }
+ cur_node = cur_node->prev;
+ new_gpd = cur_node->gpd;
}
}
- else if (step == -1) {
- // printf("\t\tGP - redo step\n");
+ else if (step == STEP_REDO) {
if (cur_node->next) {
- if (!name || STREQ(cur_node->name, name)) {
- cur_node = cur_node->next;
- new_gpd = cur_node->gpd;
- }
+ cur_node = cur_node->next;
+ new_gpd = cur_node->gpd;
}
}
@@ -99,7 +94,7 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name)
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* make a copy of source layer and its data */
- gpld = BKE_gpencil_layer_duplicate(gpl);
+ gpld = BKE_gpencil_layer_duplicate(gpl, true, true);
BLI_addtail(&gpd->layers, gpld);
}
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 7c796f7b7a1..9b12772bc9b 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -579,7 +579,7 @@ bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
}
/* Check whether given stroke can be edited for the current color */
-bool ED_gpencil_stroke_color_use(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
+bool ED_gpencil_stroke_material_editable(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
{
/* check if the color is editable */
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
@@ -674,7 +674,7 @@ void gpencil_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, b
float inverse_diff_mat[4][4];
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
for (i = 0; i < gps->totpoints; i++) {
@@ -697,10 +697,11 @@ void gpencil_apply_parent_point(Depsgraph *depsgraph,
float inverse_diff_mat[4][4];
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, 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);
}
@@ -997,6 +998,12 @@ void ED_gpencil_drawing_reference_get(const Scene *scene,
else {
/* use object location */
copy_v3_v3(r_vec, ob->obmat[3]);
+ /* Apply layer offset. */
+ bGPdata *gpd = ob->data;
+ bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
+ if (gpl != NULL) {
+ add_v3_v3(r_vec, gpl->layer_mat[3]);
+ }
}
}
}
@@ -1021,7 +1028,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
/* init space conversion stuff */
gpencil_point_conversion_init(C, &gsc);
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
/* Adjust each point */
@@ -1046,6 +1053,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
void ED_gpencil_project_stroke_to_plane(const Scene *scene,
const Object *ob,
const RegionView3D *rv3d,
+ bGPDlayer *gpl,
bGPDstroke *gps,
const float origin[3],
const int axis)
@@ -1058,6 +1066,10 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
float ray[3];
float rpoint[3];
+ /* Recalculate layer transform matrix. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
/* normal vector for a plane locked to axis */
zero_v3(plane_normal);
if (axis < 0) {
@@ -1074,24 +1086,27 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
copy_m4_m4(mat, ob->obmat);
/* move origin to cursor */
+ if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ if (gpl != NULL) {
+ add_v3_v3(mat[3], gpl->location);
+ }
+ }
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
copy_v3_v3(mat[3], cursor->location);
}
mul_mat3_m4_v3(mat, plane_normal);
}
+
+ if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
+ mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
+ }
}
else {
const float scale[3] = {1.0f, 1.0f, 1.0f};
plane_normal[2] = 1.0f;
float mat[4][4];
loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale);
-
- /* move origin to object */
- if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
- copy_v3_v3(mat[3], ob->obmat[3]);
- }
-
mul_mat3_m4_v3(mat, plane_normal);
}
@@ -1127,8 +1142,12 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
ARegion *region = gsc->region;
RegionView3D *rv3d = region->regiondata;
+ /* Recalculate layer transform matrix. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
float diff_mat[4][4], inverse_diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
float origin[3];
@@ -1194,7 +1213,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
}
}
- ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, rv3d, origin, axis, &pt2);
+ ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, gpl, rv3d, origin, axis, &pt2);
copy_v3_v3(&pt->x, &pt2.x);
@@ -1250,6 +1269,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
*/
void ED_gpencil_project_point_to_plane(const Scene *scene,
const Object *ob,
+ bGPDlayer *gpl,
const RegionView3D *rv3d,
const float origin[3],
const int axis,
@@ -1277,6 +1297,11 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
if (ob && (ob->type == OB_GPENCIL)) {
float mat[4][4];
copy_m4_m4(mat, ob->obmat);
+ if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ if (gpl != NULL) {
+ add_v3_v3(mat[3], gpl->location);
+ }
+ }
/* move origin to cursor */
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
@@ -1284,6 +1309,10 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
}
mul_mat3_m4_v3(mat, plane_normal);
+ /* Apply layer rotation (local transform). */
+ if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
+ mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
+ }
}
}
else {
@@ -1449,7 +1478,7 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata
/* only redo if any change */
if (!equals_m4m4(gpl->inverse, cur_mat)) {
/* first apply current transformation to all strokes */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
/* undo local object */
sub_v3_v3(diff_mat[3], gpl_loc);
@@ -2144,7 +2173,7 @@ void ED_gpencil_update_color_uv(Main *bmain, Material *mat)
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* check if it is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
gps_ma = BKE_gpencil_material(ob, gps->mat_nr + 1);
@@ -3003,12 +3032,12 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
}
}
-/* Helper to get the bigger 2D bound box points. */
-static void gpencil_projected_2d_bound_box(GP_SpaceConversion *gsc,
- bGPDstroke *gps,
- const float diff_mat[4][4],
- float r_min[2],
- float r_max[2])
+/* Get the bigger 2D bound box points. */
+void ED_gpencil_projected_2d_bound_box(GP_SpaceConversion *gsc,
+ bGPDstroke *gps,
+ const float diff_mat[4][4],
+ float r_min[2],
+ float r_max[2])
{
float bounds[8][2];
BoundBox bb;
@@ -3053,7 +3082,7 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
BKE_gpencil_stroke_boundingbox_calc(gps);
}
- gpencil_projected_2d_bound_box(gsc, gps, diff_mat, boundbox_min, boundbox_max);
+ ED_gpencil_projected_2d_bound_box(gsc, gps, diff_mat, boundbox_min, boundbox_max);
rcti rect_stroke = {boundbox_min[0], boundbox_max[0], boundbox_min[1], boundbox_max[1]};
@@ -3126,7 +3155,7 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
/* calculate difference matrix object */
float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
/* Calculate the extremes of the stroke in 2D. */
bGPDspoint pt_parent;
@@ -3144,15 +3173,13 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
float dist_min = FLT_MAX;
LISTBASE_FOREACH (bGPDstroke *, gps_target, &gpf->strokes) {
/* Check if the color is editable. */
- if ((gps_target == gps) || (ED_gpencil_stroke_color_use(ob, gpl, gps) == false)) {
+ if ((gps_target == gps) || (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false)) {
continue;
}
/* Check if one of the ends is inside target stroke bounding box. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, pt2d_start, radius, diff_mat)) {
- continue;
- }
- if (!ED_gpencil_stroke_check_collision(gsc, gps, 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.
diff --git a/source/blender/editors/gpencil/gpencil_uv.c b/source/blender/editors/gpencil/gpencil_uv.c
index ec2ccabddfe..677451eaabc 100644
--- a/source/blender/editors/gpencil/gpencil_uv.c
+++ b/source/blender/editors/gpencil/gpencil_uv.c
@@ -31,7 +31,6 @@
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
-#include "BKE_unit.h"
#include "RNA_access.h"
#include "RNA_define.h"
diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c
index b212872b607..bf46fa2544f 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_ops.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c
@@ -28,16 +28,11 @@
#include "BLI_ghash.h"
#include "BLI_math.h"
-#include "BLT_translation.h"
-
#include "DNA_brush_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_material_types.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_gpencil.h"
-#include "BKE_gpencil_modifier.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_paint.h"
@@ -48,16 +43,11 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "UI_view2d.h"
#include "ED_gpencil.h"
#include "ED_screen.h"
-#include "ED_view3d.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
@@ -674,7 +664,7 @@ static bool gpencil_extract_palette_from_vertex(bContext *C,
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
@@ -859,7 +849,7 @@ static int gpencil_material_to_vertex_exec(bContext *C, wmOperator *op)
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index e2c81d53fba..a05cc3c4dbd 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -151,7 +151,7 @@ typedef struct tGP_BrushVertexpaintData {
tGP_Grid *grid;
/** Total number of rows/cols. */
int grid_size;
- /** Total number of cells elments in the grid array. */
+ /** Total number of cells elements in the grid array. */
int grid_len;
/** Grid sample position (used to determine distance of falloff) */
int grid_sample[2];
@@ -825,7 +825,8 @@ static void gpencil_save_selected_point(tGP_BrushVertexpaintData *gso,
static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
bGPDstroke *gps,
const char tool,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -853,7 +854,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
}
/* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
return false;
}
@@ -998,7 +999,8 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
tGP_BrushVertexpaintData *gso,
bGPDlayer *gpl,
bGPDframe *gpf,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
const char tool = ob->mode == OB_MODE_VERTEX_GPENCIL ? gso->brush->gpencil_vertex_tool :
@@ -1020,12 +1022,12 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Check points below the brush. */
- bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat);
+ bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat, bound_mat);
/* If stroke was hit and has an editcurve the curve needs an update. */
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
@@ -1130,9 +1132,11 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
continue;
}
- /* calculate difference matrix */
- float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ /* Calculate transform matrix. */
+ float diff_mat[4][4], bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ copy_m4_m4(bound_mat, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
@@ -1159,7 +1163,7 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
}
/* affect strokes in this frame */
- changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
}
}
}
@@ -1167,7 +1171,8 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
/* Apply to active frame's strokes */
if (gpl->actframe != NULL) {
gso->mf_falloff = 1.0f;
- changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_vertexpaint_brush_do_frame(
+ C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
}
}
}
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index 7fa71fcce3c..a3e5ece5862 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -383,7 +383,8 @@ static void gpencil_save_selected_point(tGP_BrushWeightpaintData *gso,
/* Select points in this stroke and add to an array to be used later. */
static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
bGPDstroke *gps,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -402,7 +403,7 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
bool include_last = false;
/* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
return;
}
@@ -505,7 +506,8 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
tGP_BrushWeightpaintData *gso,
bGPDlayer *gpl,
bGPDframe *gpf,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
char tool = gso->brush->gpencil_weight_tool;
@@ -526,12 +528,12 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Check points below the brush. */
- gpencil_weightpaint_select_stroke(gso, gps, diff_mat);
+ gpencil_weightpaint_select_stroke(gso, gps, diff_mat, bound_mat);
}
/*---------------------------------------------------------------------
@@ -578,9 +580,11 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
continue;
}
- /* calculate difference matrix */
- float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ /* Calculate transform matrix. */
+ float diff_mat[4][4], bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ copy_m4_m4(bound_mat, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
@@ -608,7 +612,7 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
}
/* affect strokes in this frame */
- changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
}
}
}
@@ -616,7 +620,8 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
if (gpl->actframe != NULL) {
/* Apply to active frame's strokes */
gso->mf_falloff = 1.0f;
- changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_weightpaint_brush_do_frame(
+ C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
}
}
}
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index 0a66c439f79..56494f87bfe 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -99,6 +99,30 @@ void ED_space_clip_set_clip(struct bContext *C,
struct Mask *ED_space_clip_get_mask(struct SpaceClip *sc);
void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask);
+/* Locked state is used to preserve current clip editor viewport upon changes. Example usage:
+ *
+ * ...
+ *
+ * ClipViewLockState lock_state;
+ * ED_clip_view_lock_state_store(C, &lock_state);
+ *
+ * <change selection>
+ *
+ * ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
+ *
+ * These function are to be used from space clip editor context only. Otherwise debug builds will
+ * assert, release builds will crash. */
+
+typedef struct ClipViewLockState {
+ float offset_x, offset_y;
+ float lock_offset_x, lock_offset_y;
+ float zoom;
+} ClipViewLockState;
+
+void ED_clip_view_lock_state_store(const struct bContext *C, ClipViewLockState *state);
+void ED_clip_view_lock_state_restore_no_jump(const struct bContext *C,
+ const ClipViewLockState *state);
+
/* ** clip_ops.c ** */
void ED_operatormacros_clip(void);
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index d12882f0e29..7538dac1354 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -194,7 +194,7 @@ typedef enum FSMenuInsert {
FS_INSERT_SAVE = (1 << 1),
/** moves the item to the front of the list when its not already there */
FS_INSERT_FIRST = (1 << 2),
- /** just append to preseve delivered order */
+ /** just append to preserve delivered order */
FS_INSERT_LAST = (1 << 3),
} FSMenuInsert;
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 1b7caf27ecf..12aef6e9464 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -62,6 +62,8 @@ struct bAnimContext;
struct wmKeyConfig;
struct wmOperator;
+enum eUndoStepDir;
+
#define GPENCIL_MINIMUM_JOIN_DIST 20.0f
/* Reproject stroke modes. */
@@ -147,9 +149,9 @@ bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfr
bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *area, const struct bGPDstroke *gps);
bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
-bool ED_gpencil_stroke_color_use(struct Object *ob,
- const struct bGPDlayer *gpl,
- const struct bGPDstroke *gps);
+bool ED_gpencil_stroke_material_editable(struct Object *ob,
+ const struct bGPDlayer *gpl,
+ const struct bGPDstroke *gps);
/* ----------- Grease Pencil Operators ----------------- */
@@ -213,7 +215,7 @@ bool ED_gpencil_anim_copybuf_paste(struct bAnimContext *ac, const short copy_mod
/* ------------ Grease-Pencil Undo System ------------------ */
int ED_gpencil_session_active(void);
-int ED_undo_gpencil_step(struct bContext *C, int step, const char *name);
+int ED_undo_gpencil_step(struct bContext *C, const enum eUndoStepDir step);
/* ------------ Grease-Pencil Armature ------------------ */
bool ED_gpencil_add_armature(const struct bContext *C,
@@ -263,11 +265,13 @@ bool ED_object_gpencil_exit(struct Main *bmain, struct Object *ob);
void ED_gpencil_project_stroke_to_plane(const struct Scene *scene,
const struct Object *ob,
const struct RegionView3D *rv3d,
+ struct bGPDlayer *gpl,
struct bGPDstroke *gps,
const float origin[3],
const int axis);
void ED_gpencil_project_point_to_plane(const struct Scene *scene,
const struct Object *ob,
+ struct bGPDlayer *gpl,
const struct RegionView3D *rv3d,
const float origin[3],
const int axis,
@@ -366,6 +370,11 @@ bool ED_gpencil_stroke_point_is_inside(struct bGPDstroke *gps,
struct GP_SpaceConversion *gsc,
int mouse[2],
const float diff_mat[4][4]);
+void ED_gpencil_projected_2d_bound_box(struct GP_SpaceConversion *gsc,
+ struct bGPDstroke *gps,
+ const float diff_mat[4][4],
+ float r_min[2],
+ float r_max[2]);
struct bGPDstroke *ED_gpencil_stroke_nearest_to_ends(struct bContext *C,
struct GP_SpaceConversion *gsc,
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 3cc77887b1a..2f8faf1b2bd 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -95,6 +95,8 @@ typedef enum eActKeyBlock_Hold {
ACTKEYBLOCK_FLAG_ANY_HOLD = (1 << 2),
/* The curve segment uses non-bezier interpolation */
ACTKEYBLOCK_FLAG_NON_BEZIER = (1 << 3),
+ /* The block is grease pencil */
+ ACTKEYBLOCK_FLAG_GPENCIL = (1 << 4),
} eActKeyBlock_Flag;
/* *********************** Keyframe Drawing ****************************** */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index b08ab57545f..63f124798aa 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -118,7 +118,7 @@ typedef struct KeyframeEdit_CircleData {
} KeyframeEdit_CircleData;
/* ************************************************ */
-/* Non-Destuctive Editing API (keyframes_edit.c) */
+/* Non-Destructive Editing API (keyframes_edit.c) */
/* --- Defines for 'OK' polls + KeyframeEditData Flags --------- */
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index bcf52da3f69..247911bdc55 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -63,7 +63,10 @@ void ED_mask_point_pos__reverse(
struct ScrArea *area, struct ARegion *region, float x, float y, float *xr, float *yr);
void ED_mask_cursor_location_get(struct ScrArea *area, float cursor[2]);
-bool ED_mask_selected_minmax(const struct bContext *C, float min[2], float max[2]);
+bool ED_mask_selected_minmax(const struct bContext *C,
+ float min[2],
+ float max[2],
+ bool handles_as_control_point);
/* mask_draw.c */
void ED_mask_draw(const struct bContext *C, const char draw_flag, const char draw_type);
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 417cae800ea..78f354a300d 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -51,6 +51,10 @@ typedef enum {
#define NODE_GRID_STEPS 5
/* space_node.c */
+
+void ED_node_cursor_location_get(const struct SpaceNode *snode, float value[2]);
+void ED_node_cursor_location_set(struct SpaceNode *snode, const float value[2]);
+
int ED_node_tree_path_length(struct SpaceNode *snode);
void ED_node_tree_path_get(struct SpaceNode *snode, char *value);
void ED_node_tree_path_get_fixedbuf(struct SpaceNode *snode, char *value, int max_length);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index bd1a4a0c63f..73326a2d5f2 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -159,7 +159,7 @@ extern struct EnumPropertyItem prop_clear_parent_types[];
extern struct EnumPropertyItem prop_make_parent_types[];
#endif
-/* Set the object's parent, return true iff successful. */
+/* Set the object's parent, return true if successful. */
bool ED_object_parent_set(struct ReportList *reports,
const struct bContext *C,
struct Scene *scene,
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 20417634020..deb6b7502c7 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -57,15 +57,14 @@ struct wmMsgSubscribeKey;
struct wmMsgSubscribeValue;
struct wmNotifier;
struct wmOperatorType;
+struct wmRegionListenerParams;
+struct wmRegionMessageSubscribeParams;
+struct wmSpaceTypeListenerParams;
struct wmWindow;
struct wmWindowManager;
/* regions */
-void ED_region_do_listen(struct wmWindow *win,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmNotifier *note,
- const Scene *scene);
+void ED_region_do_listen(struct wmRegionListenerParams *params);
void ED_region_do_layout(struct bContext *C, struct ARegion *region);
void ED_region_do_draw(struct bContext *C, struct ARegion *region);
void ED_region_exit(struct bContext *C, struct ARegion *region);
@@ -144,29 +143,11 @@ void ED_area_do_msg_notify_tag_refresh(struct bContext *C,
struct wmMsgSubscribeKey *msg_key,
struct wmMsgSubscribeValue *msg_val);
-void ED_area_do_mgs_subscribe_for_tool_header(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
-void ED_area_do_mgs_subscribe_for_tool_ui(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_area_do_mgs_subscribe_for_tool_header(const struct wmRegionMessageSubscribeParams *params);
+void ED_area_do_mgs_subscribe_for_tool_ui(const struct wmRegionMessageSubscribeParams *params);
/* message bus */
-void ED_region_message_subscribe(struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_region_message_subscribe(struct wmRegionMessageSubscribeParams *params);
/* spaces */
void ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
@@ -178,7 +159,7 @@ void ED_area_exit(struct bContext *C, struct ScrArea *area);
int ED_screen_area_active(const struct bContext *C);
void ED_screen_global_areas_refresh(struct wmWindow *win);
void ED_screen_global_areas_sync(struct wmWindow *win);
-void ED_area_do_listen(struct wmWindow *win, ScrArea *area, struct wmNotifier *note, Scene *scene);
+void ED_area_do_listen(struct wmSpaceTypeListenerParams *params);
void ED_area_tag_redraw(ScrArea *area);
void ED_area_tag_redraw_no_rebuild(ScrArea *area);
void ED_area_tag_redraw_regiontype(ScrArea *area, int type);
@@ -427,13 +408,8 @@ void ED_region_cache_draw_cached_segments(struct ARegion *region,
const int efra);
/* area_utils.c */
-void ED_region_generic_tools_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_region_generic_tools_region_message_subscribe(
+ const struct wmRegionMessageSubscribeParams *params);
int ED_region_generic_tools_region_snap_size(const struct ARegion *region, int size, int axis);
/* area_query.c */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index ca3e351a052..8f1be847e2b 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -40,7 +40,7 @@ void transform_operatortypes(void);
/* ******************** Macros & Prototypes *********************** */
/* MODE AND NUMINPUT FLAGS */
-enum TfmMode {
+typedef enum {
TFM_INIT = -1,
TFM_DUMMY,
TFM_TRANSLATION,
@@ -77,29 +77,11 @@ enum TfmMode {
TFM_BONE_ENVELOPE_DIST,
TFM_NORMAL_ROTATION,
TFM_GPENCIL_OPACITY,
-};
-
-/* TRANSFORM CONTEXTS */
-#define CTX_NONE 0
-#define CTX_TEXTURE (1 << 0)
-#define CTX_EDGE (1 << 1)
-#define CTX_NO_PET (1 << 2)
-#define CTX_NO_MIRROR (1 << 3)
-#define CTX_AUTOCONFIRM (1 << 4)
-#define CTX_MOVIECLIP (1 << 6)
-#define CTX_MASK (1 << 7)
-#define CTX_PAINT_CURVE (1 << 8)
-#define CTX_GPENCIL_STROKES (1 << 9)
-#define CTX_CURSOR (1 << 10)
-/** When transforming object's, adjust the object data so it stays in the same place. */
-#define CTX_OBMODE_XFORM_OBDATA (1 << 11)
-/** Transform object parents without moving their children. */
-#define CTX_OBMODE_XFORM_SKIP_CHILDREN (1 << 12)
+} eTfmMode;
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
- * (if 0 is returns, *vec is unmodified)
- * */
+ * (if false is returns, `cent3d` is unmodified). */
bool calculateTransformCenter(struct bContext *C,
int centerMode,
float cent3d[3],
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 7bbb7225f14..066d262cc44 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -56,6 +56,7 @@ struct bNode;
struct bNodeSocket;
struct bNodeTree;
struct bScreen;
+struct rctf;
struct rcti;
struct uiButSearch;
struct uiFontStyle;
@@ -414,57 +415,38 @@ void UI_draw_anti_tria(
void UI_draw_anti_fan(float tri_array[][2], unsigned int length, const float color[4]);
void UI_draw_roundbox_corner_set(int type);
-void UI_draw_roundbox_aa(
- bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4]);
-void UI_draw_roundbox_4fv(
- bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4]);
-void UI_draw_roundbox_3ub_alpha(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
+void UI_draw_roundbox_aa(const struct rctf *rect, bool filled, float rad, const float color[4]);
+void UI_draw_roundbox_4fv(const struct rctf *rect, bool filled, float rad, const float col[4]);
+void UI_draw_roundbox_3ub_alpha(const struct rctf *rect,
+ bool filled,
float rad,
const unsigned char col[3],
unsigned char alpha);
-void UI_draw_roundbox_3fv_alpha(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- const float col[3],
- float alpha);
-void UI_draw_roundbox_shade_x(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
+void UI_draw_roundbox_3fv_alpha(
+ const struct rctf *rect, bool filled, float rad, const float col[3], float alpha);
+void UI_draw_roundbox_shade_x(const struct rctf *rect,
+ bool filled,
float rad,
float shadetop,
float shadedown,
const float col[4]);
+void UI_draw_roundbox_4fv_ex(const struct rctf *rect,
+ const float inner1[4],
+ const float inner2[4],
+ float shade_dir,
+ const float outline[4],
+ float outline_width,
+ float rad);
#if 0 /* unused */
int UI_draw_roundbox_corner_get(void);
-void UI_draw_roundbox_shade_y(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- float shadeleft,
- float shaderight,
- const float col[4]);
#endif
-void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
+void UI_draw_box_shadow(const struct rctf *rect, unsigned char alpha);
void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4]);
void UI_draw_safe_areas(uint pos,
- float x1,
- float x2,
- float y1,
- float y2,
+ const struct rctf *rect,
const float title_aspect[2],
const float action_aspect[2]);
@@ -526,6 +508,7 @@ typedef bool (*uiButSearchContextMenuFn)(struct bContext *C,
const struct wmEvent *event);
typedef struct ARegion *(*uiButSearchTooltipFn)(struct bContext *C,
struct ARegion *region,
+ const struct rcti *item_rect,
void *arg,
void *active);
@@ -664,8 +647,7 @@ bool UI_popup_block_name_exists(const struct bScreen *screen, const char *name);
* Begin/Define Buttons/End/Draw is the typical order in which these
* function should be called, though for popup blocks Draw is left out.
* Freeing blocks is done by the screen/ module automatically.
- *
- * */
+ */
uiBlock *UI_block_begin(const struct bContext *C,
struct ARegion *region,
@@ -1431,6 +1413,8 @@ enum {
int UI_icon_from_id(struct ID *id);
int UI_icon_from_report_type(int type);
+int UI_icon_colorid_from_report_type(int type);
+int UI_text_colorid_from_report_type(int type);
int UI_icon_from_event_type(short event_type, short event_value);
int UI_icon_from_keymap_item(const struct wmKeyMapItem *kmi, int r_icon_mod[4]);
@@ -2499,11 +2483,12 @@ void UI_context_active_but_prop_get_templateID(struct bContext *C,
struct PropertyRNA **r_prop);
struct ID *UI_context_active_but_get_tab_ID(struct bContext *C);
-uiBut *UI_region_active_but_get(struct ARegion *region);
+uiBut *UI_region_active_but_get(const struct ARegion *region);
uiBut *UI_region_but_find_rect_over(const struct ARegion *region, const struct rcti *rect_px);
uiBlock *UI_region_block_find_mouse_over(const struct ARegion *region,
const int xy[2],
bool only_clip);
+struct ARegion *UI_region_searchbox_region_get(const struct ARegion *button_region);
/* uiFontStyle.align */
typedef enum eFontStyle_Align {
@@ -2583,6 +2568,21 @@ struct ARegion *UI_tooltip_create_from_button(struct bContext *C,
struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *gz);
void UI_tooltip_free(struct bContext *C, struct bScreen *screen, struct ARegion *region);
+typedef struct {
+ /** A description for the item, e.g. what happens when selecting it. */
+ char description[UI_MAX_DRAW_STR];
+ /* The full name of the item, without prefixes or suffixes (e.g. hint with UI_SEP_CHARP). */
+ const char *name;
+ /** Additional info about the item (e.g. library name of a linked data-block). */
+ char hint[UI_MAX_DRAW_STR];
+} uiSearchItemTooltipData;
+
+struct ARegion *UI_tooltip_create_from_search_item_generic(
+ struct bContext *C,
+ const struct ARegion *searchbox_region,
+ const struct rcti *item_rect,
+ const uiSearchItemTooltipData *item_tooltip_data);
+
/* How long before a tool-tip shows. */
#define UI_TOOLTIP_DELAY 0.5
#define UI_TOOLTIP_DELAY_LABEL 0.2
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index d77a87e7200..266a538b6c3 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -23,6 +23,9 @@
#pragma once
+/* Required for #eIconSizes which can't be forward declared if this file is included in C++. */
+#include "DNA_ID_enums.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -34,8 +37,6 @@ struct PreviewImage;
struct Scene;
struct bContext;
-enum eIconSizes;
-
typedef struct IconFile {
struct IconFile *next, *prev;
char filename[256]; /* FILE_MAXFILE size */
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index c09bf41e152..1820c2f133c 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -433,7 +433,7 @@ void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3],
* (for anything fancy use UI_GetThemeColor[Fancy] then BLF_color) */
void UI_FontThemeColor(int fontid, int colorid);
-/* clear the framebuffer using the input colorid */
+/* Clear the frame-buffer using the input colorid. */
void UI_ThemeClearColor(int colorid);
/* internal (blender) usage only, for init and set active */
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 8df29e5b520..64f881052a1 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -231,7 +231,7 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C);
struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C);
void UI_view2d_scroller_size_get(const struct View2D *v2d, float *r_x, float *r_y);
-void UI_view2d_scale_get(struct View2D *v2d, float *r_x, float *r_y);
+void UI_view2d_scale_get(const struct View2D *v2d, float *r_x, float *r_y);
float UI_view2d_scale_get_x(const struct View2D *v2d);
float UI_view2d_scale_get_y(const struct View2D *v2d);
void UI_view2d_scale_get_inverse(const struct View2D *v2d, float *r_x, float *r_y);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 319ae385ffc..10cbc2dc5fa 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1284,12 +1284,10 @@ static bool ui_but_event_property_operator_string(const bContext *C,
char *buf,
const size_t buf_len)
{
- /* context toggle operator names to check... */
+ /* Context toggle operator names to check. */
/* This function could use a refactor to generalize button type to operator relationship
- * as well as which operators use properties.
- * - Campbell
- * */
+ * as well as which operators use properties. - Campbell */
const char *ctx_toggle_opnames[] = {
"WM_OT_context_toggle",
"WM_OT_context_toggle_enum",
@@ -1424,10 +1422,10 @@ static bool ui_but_event_property_operator_string(const bContext *C,
// printf("prop shortcut: '%s' (%s)\n", RNA_property_identifier(prop), data_path);
}
- /* we have a datapath! */
+ /* We have a data-path! */
bool found = false;
if (data_path || (prop_enum_value_ok && prop_enum_value_id)) {
- /* create a property to host the "datapath" property we're sending to the operators */
+ /* Create a property to host the "data_path" property we're sending to the operators. */
IDProperty *prop_path;
const IDPropertyTemplate val = {0};
@@ -1947,7 +1945,7 @@ void ui_fontscale(short *points, float aspect)
}
}
-/* project button or block (but==NULL) to pixels in regionspace */
+/* Project button or block (but==NULL) to pixels in region-space. */
static void ui_but_to_pixelrect(rcti *rect, const ARegion *region, uiBlock *block, uiBut *but)
{
rctf rectf;
@@ -4026,7 +4024,7 @@ static uiBut *ui_def_but(uiBlock *block,
but->emboss = block->emboss;
but->pie_dir = UI_RADIAL_NONE;
- but->block = block; /* pointer back, used for frontbuffer status, and picker */
+ but->block = block; /* pointer back, used for front-buffer status, and picker. */
if ((block->flag & UI_BUT_ALIGN) && ui_but_can_align(but)) {
but->alignnr = block->alignnr;
@@ -4749,7 +4747,7 @@ static int findBitIndex(uint x)
return idx;
}
-/* autocomplete helper functions */
+/* Auto-complete helper functions. */
struct AutoComplete {
size_t maxlen;
int matches;
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 85730d138ac..53a04ec9db5 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -953,7 +953,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
}
}
- /* If the button reprents an id, it can set the "id" context pointer. */
+ /* If the button represents an id, it can set the "id" context pointer. */
if (U.experimental.use_asset_browser && ED_asset_can_make_single_from_context(C)) {
ID *id = CTX_data_pointer_get_type(C, "id", &RNA_ID).data;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 5bb6b0f21e7..d10cdc207c2 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -81,544 +81,116 @@ int UI_draw_roundbox_corner_get(void)
}
#endif
-void UI_draw_roundbox_3ub_alpha(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- const uchar col[3],
- uchar alpha)
+void UI_draw_roundbox_4fv_ex(const rctf *rect,
+ const float inner1[4],
+ const float inner2[4],
+ float shade_dir,
+ const float outline[4],
+ float outline_width,
+ float rad)
{
- float colv[4];
- colv[0] = ((float)col[0]) / 255;
- colv[1] = ((float)col[1]) / 255;
- colv[2] = ((float)col[2]) / 255;
- colv[3] = ((float)alpha) / 255;
- UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
-}
-
-void UI_draw_roundbox_3fv_alpha(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- const float col[3],
- float alpha)
-{
- float colv[4];
- colv[0] = col[0];
- colv[1] = col[1];
- colv[2] = col[2];
- colv[3] = alpha;
- UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
-}
-
-void UI_draw_roundbox_aa(
- bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4])
-{
- uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx + U.pixelsize,
- .recti.ymin = miny + U.pixelsize,
- .recti.xmax = maxx - U.pixelsize,
- .recti.ymax = maxy - U.pixelsize,
- .rect.xmin = minx,
- .rect.ymin = miny,
- .rect.xmax = maxx,
- .rect.ymax = maxy,
- .radi = rad,
- .rad = rad,
- .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
- .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
- .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
- .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = filled ? color[0] : 0.0f,
- .color_inner1[1] = filled ? color[1] : 0.0f,
- .color_inner1[2] = filled ? color[2] : 0.0f,
- .color_inner1[3] = filled ? color[3] : 0.0f,
- .color_inner2[0] = filled ? color[0] : 0.0f,
- .color_inner2[1] = filled ? color[1] : 0.0f,
- .color_inner2[2] = filled ? color[2] : 0.0f,
- .color_inner2[3] = filled ? color[3] : 0.0f,
- .color_outline[0] = color[0],
- .color_outline[1] = color[1],
- .color_outline[2] = color[2],
- .color_outline[3] = color[3],
- .alpha_discard = 1.0f,
- };
-
- /* XXX this is to emulate previous behavior of semitransparent fills but that's was a side effect
- * of the previous AA method. Better fix the callers. */
- if (filled) {
- widget_params.color_inner1[3] *= 0.65f;
- widget_params.color_inner2[3] *= 0.65f;
- widget_params.color_outline[3] *= 0.65f;
- }
-
/* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
* If it has been scaled, then it's no longer valid. */
-
- GPUBatch *batch = ui_batch_roundbox_widget_get();
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
-
- GPU_blend(GPU_BLEND_ALPHA);
-
- GPU_batch_draw(batch);
-
- GPU_blend(GPU_BLEND_NONE);
-}
-
-void UI_draw_roundbox_4fv(
- bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4])
-{
-#if 0
- float vec[7][2] = {
- {0.195, 0.02},
- {0.383, 0.067},
- {0.55, 0.169},
- {0.707, 0.293},
- {0.831, 0.45},
- {0.924, 0.617},
- {0.98, 0.805},
- };
- int a;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- uint vert_len = 0;
- vert_len += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(col);
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_len);
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- immVertex2f(pos, maxx - rad, miny);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
- immVertex2f(pos, maxx, maxy - rad);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
- immVertex2f(pos, minx + rad, maxy);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- immVertex2f(pos, minx, miny + rad);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- immVertex2f(pos, minx, miny);
- }
-
- immEnd();
- immUnbindProgram();
-#endif
uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx + U.pixelsize,
- .recti.ymin = miny + U.pixelsize,
- .recti.xmax = maxx - U.pixelsize,
- .recti.ymax = maxy - U.pixelsize,
- .rect.xmin = minx,
- .rect.ymin = miny,
- .rect.xmax = maxx,
- .rect.ymax = maxy,
+ .recti.xmin = rect->xmin + outline_width,
+ .recti.ymin = rect->ymin + outline_width,
+ .recti.xmax = rect->xmax - outline_width,
+ .recti.ymax = rect->ymax - outline_width,
+ .rect = *rect,
.radi = rad,
.rad = rad,
.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = filled ? col[0] : 0.0f,
- .color_inner1[1] = filled ? col[1] : 0.0f,
- .color_inner1[2] = filled ? col[2] : 0.0f,
- .color_inner1[3] = filled ? col[3] : 0.0f,
- .color_inner2[0] = filled ? col[0] : 0.0f,
- .color_inner2[1] = filled ? col[1] : 0.0f,
- .color_inner2[2] = filled ? col[2] : 0.0f,
- .color_inner2[3] = filled ? col[3] : 0.0f,
- .color_outline[0] = col[0],
- .color_outline[1] = col[1],
- .color_outline[2] = col[2],
- .color_outline[3] = col[3],
+ .color_inner1[0] = inner1 ? inner1[0] : 0.0f,
+ .color_inner1[1] = inner1 ? inner1[1] : 0.0f,
+ .color_inner1[2] = inner1 ? inner1[2] : 0.0f,
+ .color_inner1[3] = inner1 ? inner1[3] : 0.0f,
+ .color_inner2[0] = inner2 ? inner2[0] : inner1 ? inner1[0] : 0.0f,
+ .color_inner2[1] = inner2 ? inner2[1] : inner1 ? inner1[1] : 0.0f,
+ .color_inner2[2] = inner2 ? inner2[2] : inner1 ? inner1[2] : 0.0f,
+ .color_inner2[3] = inner2 ? inner2[3] : inner1 ? inner1[3] : 0.0f,
+ .color_outline[0] = outline ? outline[0] : inner1 ? inner1[0] : 0.0f,
+ .color_outline[1] = outline ? outline[1] : inner1 ? inner1[1] : 0.0f,
+ .color_outline[2] = outline ? outline[2] : inner1 ? inner1[2] : 0.0f,
+ .color_outline[3] = outline ? outline[3] : inner1 ? inner1[3] : 0.0f,
+ .shade_dir = shade_dir,
.alpha_discard = 1.0f,
};
- /* Exactly the same as UI_draw_roundbox_aa but does not do the legacy transparency. */
-
- /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
- * If it has been scaled, then it's no longer valid. */
-
GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
-
GPU_blend(GPU_BLEND_ALPHA);
-
GPU_batch_draw(batch);
-
GPU_blend(GPU_BLEND_NONE);
}
-#if 0
-static void round_box_shade_col(uint attr,
- const float col1[3],
- float const col2[3],
- const float fac)
+void UI_draw_roundbox_3ub_alpha(
+ const rctf *rect, bool filled, float rad, const uchar col[3], uchar alpha)
{
- float col[4] = {
- fac * col1[0] + (1.0f - fac) * col2[0],
- fac * col1[1] + (1.0f - fac) * col2[1],
- fac * col1[2] + (1.0f - fac) * col2[2],
- 1.0f,
+ float colv[4] = {
+ ((float)col[0]) / 255,
+ ((float)col[1]) / 255,
+ ((float)col[2]) / 255,
+ ((float)alpha) / 255,
};
- immAttr4fv(attr, col);
+ UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : NULL, NULL, 1.0f, colv, U.pixelsize, rad);
}
-#endif
-/* linear horizontal shade within button or in outline */
-/* view2d scrollers use it */
-void UI_draw_roundbox_shade_x(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- float shadetop,
- float shadedown,
- const float col[4])
+void UI_draw_roundbox_3fv_alpha(
+ const rctf *rect, bool filled, float rad, const float col[3], float alpha)
{
-#if 0
- float vec[7][2] = {
- {0.195, 0.02},
- {0.383, 0.067},
- {0.55, 0.169},
- {0.707, 0.293},
- {0.831, 0.45},
- {0.924, 0.617},
- {0.98, 0.805},
- };
- const float div = maxy - miny;
- const float idiv = 1.0f / div;
- float coltop[3], coldown[3];
- int vert_count = 0;
- int a;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- /* 'shade' defines strength of shading */
- coltop[0] = min_ff(1.0f, col[0] + shadetop);
- coltop[1] = min_ff(1.0f, col[1] + shadetop);
- coltop[2] = min_ff(1.0f, col[2] + shadetop);
- coldown[0] = max_ff(0.0f, col[0] + shadedown);
- coldown[1] = max_ff(0.0f, col[1] + shadedown);
- coldown[2] = max_ff(0.0f, col[2] + shadedown);
-
- vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
-
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
-
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, maxx - rad, miny);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, vec[a][1] * idiv);
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
-
- round_box_shade_col(color, coltop, coldown, rad * idiv);
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
-
- round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
- immVertex2f(pos, maxx, maxy - rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (div - rad + vec[a][1]) * idiv);
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
-
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, minx + rad, maxy);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (div - vec[a][1]) * idiv);
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
-
- round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
-
- round_box_shade_col(color, coltop, coldown, rad * idiv);
- immVertex2f(pos, minx, miny + rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (rad - vec[a][1]) * idiv);
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
+ float colv[4] = {col[0], col[1], col[2], alpha};
+ UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : NULL, NULL, 1.0f, colv, U.pixelsize, rad);
+}
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, minx, miny);
+void UI_draw_roundbox_aa(const rctf *rect, bool filled, float rad, const float color[4])
+{
+ /* XXX this is to emulate previous behavior of semitransparent fills but that's was a side effect
+ * of the previous AA method. Better fix the callers. */
+ float colv[4] = {color[0], color[1], color[2], color[3]};
+ if (filled) {
+ colv[3] *= 0.65f;
}
- immEnd();
- immUnbindProgram();
-#endif
- uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx + U.pixelsize,
- .recti.ymin = miny + U.pixelsize,
- .recti.xmax = maxx - U.pixelsize,
- .recti.ymax = maxy - U.pixelsize,
- .rect.xmin = minx,
- .rect.ymin = miny,
- .rect.xmax = maxx,
- .rect.ymax = maxy,
- .radi = rad,
- .rad = rad,
- .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
- .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
- .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
- .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = !filled ? 0.0f : min_ff(1.0f, col[0] + shadetop),
- .color_inner1[1] = !filled ? 0.0f : min_ff(1.0f, col[1] + shadetop),
- .color_inner1[2] = !filled ? 0.0f : min_ff(1.0f, col[2] + shadetop),
- .color_inner1[3] = !filled ? 0.0f : 1.0f,
- .color_inner2[0] = !filled ? 0.0f : max_ff(0.0f, col[0] + shadedown),
- .color_inner2[1] = !filled ? 0.0f : max_ff(0.0f, col[1] + shadedown),
- .color_inner2[2] = !filled ? 0.0f : max_ff(0.0f, col[2] + shadedown),
- .color_inner2[3] = !filled ? 0.0f : 1.0f,
- /* TODO: non-filled box don't have gradients. Just use middle color. */
- .color_outline[0] = clamp_f(col[0] + shadetop + shadedown, 0.0f, 1.0f),
- .color_outline[1] = clamp_f(col[1] + shadetop + shadedown, 0.0f, 1.0f),
- .color_outline[2] = clamp_f(col[2] + shadetop + shadedown, 0.0f, 1.0f),
- .color_outline[3] = clamp_f(col[3] + shadetop + shadedown, 0.0f, 1.0f),
- .shade_dir = 1.0f,
- .alpha_discard = 1.0f,
- };
-
- GPU_blend(GPU_BLEND_ALPHA);
-
- GPUBatch *batch = ui_batch_roundbox_widget_get();
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
- GPU_batch_draw(batch);
+ UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : NULL, NULL, 1.0f, colv, U.pixelsize, rad);
+}
- GPU_blend(GPU_BLEND_NONE);
+void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float col[4])
+{
+ /* Exactly the same as UI_draw_roundbox_aa but does not do the legacy transparency. */
+ UI_draw_roundbox_4fv_ex(rect, (filled) ? col : NULL, NULL, 1.0f, col, U.pixelsize, rad);
}
-#if 0 /* unused */
-/* linear vertical shade within button or in outline */
+/* linear horizontal shade within button or in outline */
/* view2d scrollers use it */
-void UI_draw_roundbox_shade_y(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- float shadeleft,
- float shaderight,
- const float col[4])
+void UI_draw_roundbox_shade_x(
+ const rctf *rect, bool filled, float rad, float shadetop, float shadedown, const float col[4])
{
- float vec[7][2] = {
- {0.195, 0.02},
- {0.383, 0.067},
- {0.55, 0.169},
- {0.707, 0.293},
- {0.831, 0.45},
- {0.924, 0.617},
- {0.98, 0.805},
- };
- const float div = maxx - minx;
- const float idiv = 1.0f / div;
- float colLeft[3], colRight[3];
- int vert_count = 0;
- int a;
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- /* 'shade' defines strength of shading */
- colLeft[0] = min_ff(1.0f, col[0] + shadeleft);
- colLeft[1] = min_ff(1.0f, col[1] + shadeleft);
- colLeft[2] = min_ff(1.0f, col[2] + shadeleft);
- colRight[0] = max_ff(0.0f, col[0] + shaderight);
- colRight[1] = max_ff(0.0f, col[1] + shaderight);
- colRight[2] = max_ff(0.0f, col[2] + shaderight);
-
- vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
+ float inner1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ float inner2[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ float outline[4];
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx - rad, miny);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, vec[a][0] * idiv);
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
-
- round_box_shade_col(color, colLeft, colRight, rad * idiv);
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, maxy - rad);
-
- for (a = 0; a < 7; a++) {
-
- round_box_shade_col(color, colLeft, colRight, (div - rad - vec[a][0]) * idiv);
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
- round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
- immVertex2f(pos, minx + rad, maxy);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, (div - rad + vec[a][0]) * idiv);
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
-
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, miny + rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, (vec[a][0]) * idiv);
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
-
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, miny);
- }
-
- immEnd();
- immUnbindProgram();
+ if (filled) {
+ inner1[0] = min_ff(1.0f, col[0] + shadetop);
+ inner1[1] = min_ff(1.0f, col[1] + shadetop);
+ inner1[2] = min_ff(1.0f, col[2] + shadetop);
+ inner1[3] = 1.0f;
+ inner2[0] = max_ff(0.0f, col[0] + shadedown);
+ inner2[1] = max_ff(0.0f, col[1] + shadedown);
+ inner2[2] = max_ff(0.0f, col[2] + shadedown);
+ inner2[3] = 1.0f;
+ }
+
+ /* TODO: non-filled box don't have gradients. Just use middle color. */
+ outline[0] = clamp_f(col[0] + shadetop + shadedown, 0.0f, 1.0f);
+ outline[1] = clamp_f(col[1] + shadetop + shadedown, 0.0f, 1.0f);
+ outline[2] = clamp_f(col[2] + shadetop + shadedown, 0.0f, 1.0f);
+ outline[3] = clamp_f(col[3] + shadetop + shadedown, 0.0f, 1.0f);
+
+ UI_draw_roundbox_4fv_ex(rect, inner1, inner2, 1.0f, outline, U.pixelsize, rad);
}
-#endif /* unused */
void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
{
@@ -783,7 +355,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
GPU_blend(GPU_BLEND_NONE);
# if 0
- /* restore scissortest */
+ /* Restore scissor-test. */
GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
# endif
@@ -799,15 +371,12 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
* \param x1, x2, y1, y2: The offsets for the view, not the zones.
*/
void UI_draw_safe_areas(uint pos,
- float x1,
- float x2,
- float y1,
- float y2,
+ const rctf *rect,
const float title_aspect[2],
const float action_aspect[2])
{
- const float size_x_half = (x2 - x1) * 0.5f;
- const float size_y_half = (y2 - y1) * 0.5f;
+ const float size_x_half = (rect->xmax - rect->xmin) * 0.5f;
+ const float size_y_half = (rect->ymax - rect->ymin) * 0.5f;
const float *safe_areas[] = {title_aspect, action_aspect};
const int safe_len = ARRAY_SIZE(safe_areas);
@@ -817,10 +386,10 @@ void UI_draw_safe_areas(uint pos,
const float margin_x = safe_areas[i][0] * size_x_half;
const float margin_y = safe_areas[i][1] * size_y_half;
- const float minx = x1 + margin_x;
- const float miny = y1 + margin_y;
- const float maxx = x2 - margin_x;
- const float maxy = y2 - margin_y;
+ const float minx = rect->xmin + margin_x;
+ const float miny = rect->ymin + margin_y;
+ const float maxx = rect->xmax - margin_x;
+ const float maxy = rect->ymax - margin_y;
imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
}
@@ -835,7 +404,15 @@ static void draw_scope_end(const rctf *rect)
UI_draw_roundbox_corner_set(UI_CNR_ALL);
const float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
UI_draw_roundbox_4fv(
- false, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect->xmin - 1,
+ .xmax = rect->xmax + 1,
+ .ymin = rect->ymin,
+ .ymax = rect->ymax + 1,
+ },
+ false,
+ 3.0f,
+ color);
}
static void histogram_draw_one(float r,
@@ -928,7 +505,15 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region),
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin - 1,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
/* need scissor test, histogram can draw outside of boundary */
int scissor[4];
@@ -1070,7 +655,15 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin - 1,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
/* need scissor test, waveform can draw outside of boundary */
GPU_scissor_get(scissor);
@@ -1399,7 +992,15 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region),
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin - 1,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
/* need scissor test, hvectorscope can draw outside of boundary */
int scissor[4];
@@ -1774,7 +1375,16 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec
/* backdrop */
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_3ub_alpha(
- true, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f, wcol->inner, 255);
+ &(const rctf){
+ .xmin = rect->xmin,
+ .xmax = rect->xmax,
+ .ymin = rect->ymin,
+ .ymax = rect->ymax,
+ },
+ true,
+ 5.0f,
+ wcol->inner,
+ 255);
GPU_face_culling(GPU_CULL_BACK);
@@ -1800,7 +1410,7 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec
GPU_batch_uniform_3fv(sphere, "light", light);
GPU_batch_draw(sphere);
- /* restore */
+ /* Restore. */
GPU_face_culling(GPU_CULL_NONE);
/* AA circle */
@@ -2130,7 +1740,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol,
immEnd();
immUnbindProgram();
- /* restore scissortest */
+ /* Restore scissor-test. */
GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
/* outline */
@@ -2420,7 +2030,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
}
immUnbindProgram();
- /* restore scissortest */
+ /* Restore scissor-test. */
GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
/* Outline */
@@ -2465,7 +2075,15 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
const float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
ok = true;
}
@@ -2514,7 +2132,15 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
}
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
@@ -2577,7 +2203,15 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
}
/* Restore scissor test. */
@@ -2594,14 +2228,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
* would replace / modify the following 3 functions - merwin
*/
-static void ui_shadowbox(uint pos,
- uint color,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float shadsize,
- uchar alpha)
+static void ui_shadowbox(const rctf *rect, uint pos, uint color, float shadsize, uchar alpha)
{
/**
* <pre>
@@ -2616,16 +2243,16 @@ static void ui_shadowbox(uint pos,
* v8______v6_-
* </pre>
*/
- const float v1[2] = {maxx, maxy - 0.3f * shadsize};
- const float v2[2] = {maxx + shadsize, maxy - 0.75f * shadsize};
- const float v3[2] = {maxx, miny};
- const float v4[2] = {maxx + shadsize, miny};
+ const float v1[2] = {rect->xmax, rect->ymax - 0.3f * shadsize};
+ const float v2[2] = {rect->xmax + shadsize, rect->ymax - 0.75f * shadsize};
+ const float v3[2] = {rect->xmax, rect->ymin};
+ const float v4[2] = {rect->xmax + shadsize, rect->ymin};
- const float v5[2] = {maxx + 0.7f * shadsize, miny - 0.7f * shadsize};
+ const float v5[2] = {rect->xmax + 0.7f * shadsize, rect->ymin - 0.7f * shadsize};
- const float v6[2] = {maxx, miny - shadsize};
- const float v7[2] = {minx + 0.3f * shadsize, miny};
- const float v8[2] = {minx + 0.5f * shadsize, miny - shadsize};
+ const float v6[2] = {rect->xmax, rect->ymin - shadsize};
+ const float v7[2] = {rect->xmin + 0.3f * shadsize, rect->ymin};
+ const float v8[2] = {rect->xmin + 0.5f * shadsize, rect->ymin - shadsize};
/* right quad */
immAttr4ub(color, 0, 0, 0, alpha);
@@ -2664,7 +2291,7 @@ static void ui_shadowbox(uint pos,
immVertex2fv(pos, v3);
}
-void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float maxy)
+void UI_draw_box_shadow(const rctf *rect, uchar alpha)
{
GPU_blend(GPU_BLEND_ALPHA);
@@ -2678,9 +2305,9 @@ void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float m
immBegin(GPU_PRIM_TRIS, 54);
/* accumulated outline boxes to make shade not linear, is more pleasant */
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8);
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8);
+ ui_shadowbox(rect, pos, color, 11.0, (20 * alpha) >> 8);
+ ui_shadowbox(rect, pos, color, 7.0, (40 * alpha) >> 8);
+ ui_shadowbox(rect, pos, color, 5.0, (80 * alpha) >> 8);
immEnd();
@@ -2755,13 +2382,16 @@ void ui_draw_dropshadow(
/* outline emphasis */
const float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
- UI_draw_roundbox_4fv(false,
- rct->xmin - 0.5f,
- rct->ymin - 0.5f,
- rct->xmax + 0.5f,
- rct->ymax + 0.5f,
- radius + 0.5f,
- color);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = rct->xmin - 0.5f,
+ .xmax = rct->xmax + 0.5f,
+ .ymin = rct->ymin - 0.5f,
+ .ymax = rct->ymax + 0.5f,
+ },
+ false,
+ radius + 0.5f,
+ color);
GPU_blend(GPU_BLEND_NONE);
}
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 4d0e1584156..de39484bc1e 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -24,8 +24,6 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "BLI_blenlib.h"
-
#include "BKE_context.h"
#include "BKE_screen.h"
diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c
index ead65a62226..a4adbef0b94 100644
--- a/source/blender/editors/interface/interface_eyedropper_depth.c
+++ b/source/blender/editors/interface/interface_eyedropper_depth.c
@@ -41,8 +41,6 @@
#include "BKE_screen.h"
#include "BKE_unit.h"
-#include "DEG_depsgraph.h"
-
#include "RNA_access.h"
#include "UI_interface.h"
@@ -66,9 +64,9 @@ typedef struct DepthDropper {
bool is_undo;
bool is_set;
- float init_depth; /* for resetting on cancel */
+ float init_depth; /* For resetting on cancel. */
- bool accum_start; /* has mouse been presed */
+ bool accum_start; /* Has mouse been pressed. */
float accum_depth;
int accum_tot;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 97d9b225d3c..1bfd84a7046 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -349,7 +349,7 @@ typedef struct uiHandleButtonData {
#endif
ColorBand *coba;
- /* tooltip */
+ /* Tool-tip. */
uint tooltip_force : 1;
/* auto open */
@@ -1617,7 +1617,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void
static bool ui_but_is_drag_toggle(const uiBut *but)
{
return ((ui_drag_toggle_but_is_supported(but) == true) &&
- /* menu check is importnt so the button dragged over isn't removed instantly */
+ /* Menu check is important so the button dragged over isn't removed instantly. */
(ui_block_is_menu(but->block) == false));
}
@@ -3710,9 +3710,9 @@ static void ui_do_but_textedit(
case EVT_AKEY:
- /* Ctrl + A: Select all */
+ /* Ctrl-A: Select all. */
#if defined(__APPLE__)
- /* OSX uses cmd-a systemwide, so add it */
+ /* OSX uses Command-A system-wide, so add it. */
if ((event->oskey && !IS_EVENT_MOD(event, shift, alt, ctrl)) ||
(event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey)))
#else
@@ -3726,7 +3726,7 @@ static void ui_do_but_textedit(
break;
case EVT_TABKEY:
- /* there is a key conflict here, we can't tab with autocomplete */
+ /* There is a key conflict here, we can't tab with auto-complete. */
if (but->autocomplete_func || data->searchbox) {
const int autocomplete = ui_textedit_autocomplete(C, but, data);
changed = autocomplete != AUTOCOMPLETE_NO_MATCH;
@@ -3735,13 +3735,14 @@ static void ui_do_but_textedit(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
- /* the hotkey here is not well defined, was G.qual so we check all */
- else if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
- ui_textedit_prev_but(block, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- ui_textedit_next_but(block, but, data);
+ else if (!IS_EVENT_MOD(event, ctrl, alt, oskey)) {
+ /* Use standard keys for cycling through buttons Tab, Shift-Tab to reverse. */
+ if (event->shift) {
+ ui_textedit_prev_but(block, but, data);
+ }
+ else {
+ ui_textedit_next_but(block, but, data);
+ }
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
retval = WM_UI_HANDLER_BREAK;
@@ -4575,7 +4576,7 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons
return WM_UI_HANDLER_BREAK;
}
if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
- /* Support ctrl-wheel to cycle values on expanded enum rows. */
+ /* Support Ctrl-Wheel to cycle values on expanded enum rows. */
if (but->type == UI_BTYPE_ROW) {
int type = event->type;
int val = event->val;
@@ -5086,7 +5087,7 @@ static int ui_do_but_NUM(
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (data->dragchange) {
#ifdef USE_DRAG_MULTINUM
- /* if we started multibutton but didn't drag, then edit */
+ /* If we started multi-button but didn't drag, then edit. */
if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
click = 1;
}
@@ -5408,7 +5409,7 @@ static int ui_do_but_SLI(
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (data->dragchange) {
#ifdef USE_DRAG_MULTINUM
- /* if we started multibutton but didn't drag, then edit */
+ /* If we started multi-button but didn't drag, then edit. */
if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
click = 1;
}
@@ -6836,7 +6837,7 @@ static bool ui_numedit_but_CURVE(uiBlock *block,
#ifdef USE_CONT_MOUSE_CORRECT
/* note: using 'cmp_last' is weak since there may be multiple points selected,
- * but in practice this isnt really an issue */
+ * but in practice this isn't really an issue */
if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
data->ungrab_mval[0] = but->rect.xmin + ((cmp_last->x - cumap->curr.xmin) * zoomx);
@@ -7107,7 +7108,7 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
changed = true;
#ifdef USE_CONT_MOUSE_CORRECT
/* note: using 'cmp_last' is weak since there may be multiple points selected,
- * but in practice this isnt really an issue */
+ * but in practice this isn't really an issue */
if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
data->ungrab_mval[0] = but->rect.xmin + ((last_x - profile->view_rect.xmin) * zoomx);
@@ -7822,7 +7823,7 @@ static void ui_blocks_set_tooltips(ARegion *region, const bool enable)
}
/**
- * Recreate tooltip (use to update dynamic tips)
+ * Recreate tool-tip (use to update dynamic tips)
*/
void UI_but_tooltip_refresh(bContext *C, uiBut *but)
{
@@ -7921,7 +7922,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
return;
}
- /* highlight has timers for tooltips and auto open */
+ /* Highlight has timers for tool-tips and auto open. */
if (state == BUTTON_STATE_HIGHLIGHT) {
but->flag &= ~UI_SELECT;
@@ -8261,7 +8262,7 @@ static void button_activate_exit(
}
}
- /* disable tooltips until mousemove + last active flag */
+ /* Disable tool-tips until mouse-move + last active flag. */
LISTBASE_FOREACH (uiBlock *, block_iter, &data->region->uiblocks) {
LISTBASE_FOREACH (uiBut *, bt, &block_iter->buttons) {
bt->flag &= ~UI_BUT_LAST_ACTIVE;
@@ -8325,7 +8326,7 @@ void ui_but_active_free(const bContext *C, uiBut *but)
}
/* returns the active button with an optional checking function */
-static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiBut *))
+static uiBut *ui_context_button_active(const ARegion *region, bool (*but_check_cb)(const uiBut *))
{
uiBut *but_found = NULL;
@@ -8349,7 +8350,7 @@ static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiB
but_found = activebut;
- /* recurse into opened menu, like colorpicker case */
+ /* Recurse into opened menu, like color-picker case. */
if (data && data->menu && (region != data->menu->region)) {
region = data->menu->region;
}
@@ -8366,7 +8367,7 @@ static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiB
return but_found;
}
-static bool ui_context_rna_button_active_test(uiBut *but)
+static bool ui_context_rna_button_active_test(const uiBut *but)
{
return (but->rnapoin.data != NULL);
}
@@ -8391,7 +8392,7 @@ uiBut *UI_context_active_but_get_respect_menu(const bContext *C)
return ui_context_button_active(region_menu ? region_menu : CTX_wm_region(C), NULL);
}
-uiBut *UI_region_active_but_get(ARegion *region)
+uiBut *UI_region_active_but_get(const ARegion *region)
{
return ui_context_button_active(region, NULL);
}
@@ -8489,6 +8490,15 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C)
return NULL;
}
+/**
+ * Try to find a search-box region opened from a button in \a button_region.
+ */
+ARegion *UI_region_searchbox_region_get(const ARegion *button_region)
+{
+ uiBut *but = UI_region_active_but_get(button_region);
+ return (but != NULL) ? but->active->searchbox : NULL;
+}
+
/* helper function for insert keyframe, reset to default, etc operators */
void UI_context_update_anim_flag(const bContext *C)
{
@@ -8522,7 +8532,7 @@ void UI_context_update_anim_flag(const bContext *C)
}
if (activebut) {
- /* always recurse into opened menu, so all buttons update (like colorpicker) */
+ /* Always recurse into opened menu, so all buttons update (like color-picker). */
uiHandleButtonData *data = activebut->active;
if (data && data->menu) {
region = data->menu->region;
@@ -8564,7 +8574,8 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *reg
button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER);
if (event->alt && but->active) {
- /* display tooltips if holding alt on mouseover when tooltips are off in prefs */
+ /* Display tool-tips if holding Alt on mouse-over when tool-tips are disabled in the
+ * preferences. */
but->active->tooltip_force = true;
}
}
@@ -8606,7 +8617,7 @@ void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but)
* Simulate moving the mouse over a button (or navigating to it with arrow keys).
*
* exported so menus can start with a highlighted button,
- * even if the mouse isnt over it
+ * even if the mouse isn't over it
*/
void ui_but_activate_over(bContext *C, ARegion *region, uiBut *but)
{
@@ -8786,7 +8797,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (event->x != event->prevx || event->y != event->prevy) {
- /* re-enable tooltip on mouse move */
+ /* Re-enable tool-tip on mouse move. */
ui_blocks_set_tooltips(region, true);
button_tooltip_timer_reset(C, but);
}
@@ -8810,7 +8821,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
break;
}
/* XXX hardcoded keymap check... but anyway,
- * while view changes, tooltips should be removed */
+ * while view changes, tool-tips should be removed */
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
case MIDDLEMOUSE:
@@ -9513,7 +9524,7 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
/* pass, skip for dialogs */
}
else if (!ui_region_contains_point_px(but->active->region, event->x, event->y)) {
- /* pass, needed to click-exit outside of non-flaoting menus */
+ /* Pass, needed to click-exit outside of non-floating menus. */
ui_region_auto_open_clear(but->active->region);
}
else if ((!ELEM(event->type, MOUSEMOVE, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN)) &&
@@ -10135,7 +10146,7 @@ static int ui_handle_menu_event(bContext *C,
ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false);
- /* check for all parent rects, enables arrowkeys to be used */
+ /* Check for all parent rects, enables arrow-keys to be used. */
for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
/* for mouse move we only check our own rect, for other
* events we check all preceding block rects too to make
@@ -10409,7 +10420,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
}
}
- /* check pie velociy here if gesture has ended */
+ /* Check pie velocity here if gesture has ended. */
if (block->pie_data.flags & UI_PIE_GESTURE_END_WAIT) {
float len_sq = 10;
@@ -10735,7 +10746,7 @@ static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(use
}
}
- /* re-enable tooltips */
+ /* Re-enable tool-tips. */
if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
ui_blocks_set_tooltips(region, true);
}
@@ -10832,7 +10843,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
}
}
- /* re-enable tooltips */
+ /* Re-enable tool-tips. */
if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
ui_blocks_set_tooltips(region, true);
}
@@ -10926,7 +10937,7 @@ static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata)
WM_event_add_mousemove(win);
}
else {
- /* re-enable tooltips */
+ /* Re-enable tool-tips */
if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
ui_blocks_set_tooltips(menu->region, true);
}
@@ -10936,7 +10947,7 @@ static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata)
ui_apply_but_funcs_after(C);
if (reset_pie) {
- /* reaqcuire window in case pie invalidates it somehow */
+ /* Reacquire window in case pie invalidates it somehow. */
wmWindow *win = CTX_wm_window(C);
if (win) {
diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c
index 223fcbfd45b..3962ff6a702 100644
--- a/source/blender/editors/interface/interface_icons_event.c
+++ b/source/blender/editors/interface/interface_icons_event.c
@@ -118,7 +118,15 @@ void icon_draw_rect_input(float x,
UI_GetThemeColor4fv(TH_TEXT, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(
- false, (int)x - U.pixelsize, (int)y, (int)(x + w), (int)(y + h), 3.0f * U.pixelsize, color);
+ &(const rctf){
+ .xmin = (int)x - U.pixelsize,
+ .xmax = (int)(x + w),
+ .ymin = (int)y,
+ .ymax = (int)(y + h),
+ },
+ false,
+ 3.0f * U.pixelsize,
+ color);
const enum {
UNIX,
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index f4e68ca3909..6a921f3f541 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -525,7 +525,7 @@ struct uiBlock {
/** for doing delayed */
int bounds, minbounds;
- /** pulldowns, to detect outside, can differ per case how it is created */
+ /** pull-downs, to detect outside, can differ per case how it is created. */
rctf safety;
/** uiSafetyRct list */
ListBase saferct;
@@ -659,7 +659,7 @@ void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3]);
/* interface_regions.c */
struct uiKeyNavLock {
- /* set when we're using keyinput */
+ /* Set when we're using key-input. */
bool is_keynav;
/* only used to check if we've moved the cursor */
int event_xy[2];
@@ -756,7 +756,7 @@ uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, voi
ColorPicker *ui_block_colorpicker_create(struct uiBlock *block);
/* interface_region_search.c */
-/* Searchbox for string button */
+/* Search-box for string button. */
struct ARegion *ui_searchbox_create_generic(struct bContext *C,
struct ARegion *butregion,
uiButSearch *search_but);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 3281b8de920..fef243d7193 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -2642,7 +2642,7 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname
static void search_id_collection(StructRNA *ptype, PointerRNA *r_ptr, PropertyRNA **r_prop)
{
/* look for collection property in Main */
- /* Note: using global Main is OK-ish here, UI shall not access other Mains anyay... */
+ /* NOTE: using global Main is OK-ish here, UI shall not access other Mains anyway. */
RNA_main_pointer_create(G_MAIN, r_ptr);
*r_prop = NULL;
@@ -2821,7 +2821,7 @@ void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
UI_menutype_draw(C, mt, layout);
- /* menus are created flipped (from event handling pov) */
+ /* Menus are created flipped (from event handling point of view). */
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index e5aa0665a16..05a2a6ef29b 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -901,7 +901,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
MEM_freeN(link);
}
else {
- /* avoid prepending 'data' to the path */
+ /* Avoid prepending 'data' to the path. */
RNA_id_pointer_create(id_data, &link->ptr);
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index bf140eb1692..7343417137a 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -926,9 +926,9 @@ bool UI_panel_matches_search_filter(const Panel *panel)
/**
* Set the flag telling the panel to use its search result status for its expansion.
*/
-static void panel_set_expansion_from_seach_filter_recursive(const bContext *C,
- Panel *panel,
- const bool use_search_closed)
+static void panel_set_expansion_from_search_filter_recursive(const bContext *C,
+ Panel *panel,
+ const bool use_search_closed)
{
/* This has to run on inactive panels that may not have a type,
* but we can prevent running on header-less panels in some cases. */
@@ -939,21 +939,21 @@ static void panel_set_expansion_from_seach_filter_recursive(const bContext *C,
LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
/* Don't check if the sub-panel is active, otherwise the
* expansion won't be reset when the parent is closed. */
- panel_set_expansion_from_seach_filter_recursive(C, child_panel, use_search_closed);
+ panel_set_expansion_from_search_filter_recursive(C, child_panel, use_search_closed);
}
}
/**
* Set the flag telling every panel to override its expansion with its search result status.
*/
-static void region_panels_set_expansion_from_seach_filter(const bContext *C,
- ARegion *region,
- const bool use_search_closed)
+static void region_panels_set_expansion_from_search_filter(const bContext *C,
+ ARegion *region,
+ const bool use_search_closed)
{
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
/* Don't check if the panel is active, otherwise the expansion won't
* be correct when switching back to tab after exiting search. */
- panel_set_expansion_from_seach_filter_recursive(C, panel, use_search_closed);
+ panel_set_expansion_from_search_filter_recursive(C, panel, use_search_closed);
}
set_panels_list_data_expand_flag(C, region);
}
@@ -1121,13 +1121,16 @@ static void panel_draw_highlight_border(const Panel *panel,
float color[4];
UI_GetThemeColor4fv(TH_SELECT_ACTIVE, color);
- UI_draw_roundbox_4fv(false,
- rect->xmin,
- UI_panel_is_closed(panel) ? header_rect->ymin : rect->ymin,
- rect->xmax,
- header_rect->ymax,
- radius,
- color);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = rect->xmin,
+ .xmax = rect->xmax,
+ .ymin = UI_panel_is_closed(panel) ? header_rect->ymin : rect->ymin,
+ .ymax = header_rect->ymax,
+ },
+ false,
+ radius,
+ color);
}
static void panel_draw_aligned_widgets(const uiStyle *style,
@@ -1253,13 +1256,16 @@ static void panel_draw_aligned_backdrop(const Panel *panel,
float color[4];
UI_GetThemeColor4fv(TH_PANEL_SUB_BACK, color);
/* Change the width a little bit to line up with sides. */
- UI_draw_roundbox_aa(true,
- rect->xmin + U.pixelsize,
- rect->ymin + U.pixelsize,
- rect->xmax - U.pixelsize,
- rect->ymax,
- box_wcol->roundness * U.widget_unit,
- color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = rect->xmin + U.pixelsize,
+ .xmax = rect->xmax - U.pixelsize,
+ .ymin = rect->ymin + U.pixelsize,
+ .ymax = rect->ymax,
+ },
+ true,
+ box_wcol->roundness * U.widget_unit,
+ color);
}
else {
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1333,7 +1339,7 @@ void ui_draw_aligned_panel(const uiStyle *style,
{
const Panel *panel = block->panel;
- /* Add 0.001f to prevent flicker frpm float inaccuracy. */
+ /* Add 0.001f to prevent flicker from float inaccuracy. */
const rcti header_rect = {
rect->xmin,
rect->xmax,
@@ -1544,20 +1550,26 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
{
/* Draw filled rectangle and outline for tab. */
UI_draw_roundbox_corner_set(roundboxtype);
- UI_draw_roundbox_4fv(true,
- rct->xmin,
- rct->ymin,
- rct->xmax,
- rct->ymax,
- tab_curve_radius,
- is_active ? theme_col_tab_active : theme_col_tab_inactive);
- UI_draw_roundbox_4fv(false,
- rct->xmin,
- rct->ymin,
- rct->xmax,
- rct->ymax,
- tab_curve_radius,
- theme_col_tab_outline);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymin,
+ .ymax = rct->ymax,
+ },
+ true,
+ tab_curve_radius,
+ is_active ? theme_col_tab_active : theme_col_tab_inactive);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymin,
+ .ymax = rct->ymax,
+ },
+ false,
+ tab_curve_radius,
+ theme_col_tab_outline);
/* Disguise the outline on one side to join the tab to the panel. */
pos = GPU_vertformat_attr_add(
@@ -1911,10 +1923,10 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
const bool region_search_filter_active = region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE;
if (properties_space_needs_realign(area, region)) {
- region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active);
+ region_panels_set_expansion_from_search_filter(C, region, region_search_filter_active);
}
else if (region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) {
- region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active);
+ region_panels_set_expansion_from_search_filter(C, region, region_search_filter_active);
}
if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) {
@@ -2354,7 +2366,7 @@ static int ui_handle_panel_category_cycling(const wmEvent *event,
PanelCategoryDyn *pc_dyn = UI_panel_category_find(region, category);
if (LIKELY(pc_dyn)) {
if (is_mousewheel) {
- /* We can probably get rid of this and only allow ctrl-tabbing. */
+ /* We can probably get rid of this and only allow Ctrl-Tabbing. */
pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
}
else {
diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.c
index d047d5421d7..81c627816b9 100644
--- a/source/blender/editors/interface/interface_region_menu_pie.c
+++ b/source/blender/editors/interface/interface_region_menu_pie.c
@@ -392,7 +392,7 @@ void ui_pie_menu_level_create(uiBlock *block,
EnumPropertyItem *remaining = MEM_mallocN(array_size + sizeof(EnumPropertyItem),
"pie_level_item_array");
memcpy(remaining, items + totitem_parent, array_size);
- /* a NULL terminating sentinal element is required */
+ /* A NULL terminating sentinel element is required. */
memset(&remaining[totitem_remain], 0, sizeof(EnumPropertyItem));
/* yuk, static... issue is we can't reliably free this without doing dangerous changes */
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 93e3dbb2cc8..3228e9741bb 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -413,12 +413,11 @@ static void ui_block_region_draw(const bContext *C, ARegion *region)
/**
* Use to refresh centered popups on screen resizing (for splash).
*/
-static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void ui_block_region_popup_window_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
switch (wmn->category) {
case NC_WINDOW: {
switch (wmn->action) {
@@ -540,7 +539,7 @@ static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
CTX_wm_window_set(C, win);
ui_region_temp_remove(C, screen, handle->region);
- /* Reset context (area and region were NULL'ed when chaning context window). */
+ /* Reset context (area and region were NULL'ed when changing context window). */
CTX_wm_window_set(C, ctx_win);
CTX_wm_area_set(C, ctx_area);
CTX_wm_region_set(C, ctx_region);
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 816162e9aa2..d1d4290bd11 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -289,7 +289,7 @@ int ui_searchbox_find_index(ARegion *region, const char *name)
return UI_search_items_find_index(&data->items, name);
}
-/* x and y in screencoords */
+/* x and y in screen-coords. */
bool ui_searchbox_inside(ARegion *region, int x, int y)
{
uiSearchboxData *data = region->regiondata;
@@ -347,9 +347,20 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C,
}
uiButSearch *search_but = (uiButSearch *)but;
- if (search_but->item_tooltip_fn) {
- return search_but->item_tooltip_fn(C, region, search_but->arg, search_but->item_active);
+ if (!search_but->item_tooltip_fn) {
+ continue;
}
+
+ ARegion *searchbox_region = UI_region_searchbox_region_get(region);
+ uiSearchboxData *data = searchbox_region->regiondata;
+
+ BLI_assert(data->items.pointers[data->active] == search_but->item_active);
+
+ rcti rect;
+ ui_searchbox_butrect(&rect, data, data->active);
+
+ return search_but->item_tooltip_fn(
+ C, region, &rect, search_but->arg, search_but->item_active);
}
}
return NULL;
@@ -452,8 +463,11 @@ static void ui_searchbox_update_fn(bContext *C,
const char *str,
uiSearchItems *items)
{
- wmWindow *win = CTX_wm_window(C);
- WM_tooltip_clear(C, win);
+ /* While the button is in text editing mode (searchbox open), remove tooltips on every update. */
+ if (search_but->but.editstr) {
+ wmWindow *win = CTX_wm_window(C);
+ WM_tooltip_clear(C, win);
+ }
search_but->items_update_fn(C, search_but->arg, str, items);
}
@@ -1046,7 +1060,7 @@ void ui_but_search_refresh(uiButSearch *search_but)
ui_searchbox_update_fn(but->block->evil_C, search_but, but->drawstr, items);
- /* only redalert when we are sure of it, this can miss cases when >10 matches */
+ /* Only red-alert when we are sure of it, this can miss cases when >10 matches. */
if (items->totitem == 0) {
UI_but_flag_enable(but, UI_BUT_REDALERT);
}
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 2bf63955855..050a14cf574 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -1456,15 +1456,91 @@ 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];
+ float init_position[2] = {win->eventstate->x, win->eventstate->y};
uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz);
if (data == NULL) {
return NULL;
}
+ /* TODO(harley):
+ * Julian preferred that the gizmo callback return the 3D bounding box
+ * which we then project to 2D here. Would make a nice improvement.
+ */
+ if (gz->type->screen_bounds_get) {
+ rcti bounds;
+ gz->type->screen_bounds_get(C, gz, &bounds);
+ init_position[0] = bounds.xmin;
+ init_position[1] = bounds.ymin;
+ }
+
+ return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect);
+}
+
+static uiTooltipData *ui_tooltip_data_from_search_item_tooltip_data(
+ const uiSearchItemTooltipData *item_tooltip_data)
+{
+ uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
+
+ if (item_tooltip_data->description[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_HEADER,
+ .color_id = UI_TIP_LC_NORMAL,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(item_tooltip_data->description);
+ }
+
+ if (item_tooltip_data->name && item_tooltip_data->name[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(item_tooltip_data->name);
+ }
+ if (item_tooltip_data->hint[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(item_tooltip_data->hint);
+ }
+
+ if (data->fields_len == 0) {
+ MEM_freeN(data);
+ return NULL;
+ }
+ return data;
+}
+
+/**
+ * Create a tooltip from search-item tooltip data \a item_tooltip data.
+ * To be called from a callback set with #UI_but_func_search_set_tooltip().
+ *
+ * \param item_rect: Rectangle of the search item in search region space (#ui_searchbox_butrect())
+ * which is passed to the tooltip callback.
+ */
+ARegion *UI_tooltip_create_from_search_item_generic(
+ bContext *C,
+ const ARegion *searchbox_region,
+ const rcti *item_rect,
+ const uiSearchItemTooltipData *item_tooltip_data)
+{
+ uiTooltipData *data = ui_tooltip_data_from_search_item_tooltip_data(item_tooltip_data);
+ if (data == NULL) {
+ return NULL;
+ }
+
+ const float aspect = 1.0f;
+ const wmWindow *win = CTX_wm_window(C);
+ float init_position[2];
init_position[0] = win->eventstate->x;
- init_position[1] = win->eventstate->y;
+ init_position[1] = item_rect->ymin + searchbox_region->winrct.ymin - (UI_POPUP_MARGIN / 2);
return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect);
}
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index a37fb0dfde1..eaefc2c3736 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -341,13 +341,16 @@ void UI_fontstyle_draw_simple_backdrop(const uiFontStyle *fs,
const float color[4] = {col_bg[0], col_bg[1], col_bg[2], 0.5f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- x - margin,
- (y + decent) - margin,
- x + width + margin,
- (y + decent) + height + margin,
- margin,
- color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = x - margin,
+ .xmax = x + width + margin,
+ .ymin = (y + decent) - margin,
+ .ymax = (y + decent) + height + margin,
+ },
+ true,
+ margin,
+ color);
}
BLF_position(fs->uifont_id, x, y, 0.0f);
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 9f4cd32588d..25cf2e12377 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -1069,6 +1069,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),
void *arg,
void *active)
{
diff --git a/source/blender/editors/interface/interface_template_search_operator.c b/source/blender/editors/interface/interface_template_search_operator.c
index 21529a97c01..ff0f9a2e5cd 100644
--- a/source/blender/editors/interface/interface_template_search_operator.c
+++ b/source/blender/editors/interface/interface_template_search_operator.c
@@ -23,11 +23,8 @@
#include <string.h>
-#include "DNA_gpencil_modifier_types.h"
-#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_shader_fx_types.h"
#include "DNA_texture_types.h"
#include "BLI_alloca.h"
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 003bb110baf..dad8253d101 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -208,6 +208,7 @@ static uiBlock *template_common_search_menu(const bContext *C,
void *search_arg,
uiButHandleFunc search_exec_fn,
void *active_item,
+ uiButSearchTooltipFn item_tooltip_fn,
const int preview_rows,
const int preview_cols,
float scale)
@@ -284,6 +285,7 @@ static uiBlock *template_common_search_menu(const bContext *C,
NULL,
search_exec_fn,
active_item);
+ UI_but_func_search_set_tooltip(but, item_tooltip_fn);
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
UI_block_direction_set(block, UI_DIR_DOWN);
@@ -347,7 +349,7 @@ static bool id_search_allows_id(TemplateID *template_ui, const int flag, ID *id,
}
}
- /* Hide dot-datablocks, but only if filter does not force them visible. */
+ /* Hide dot prefixed data-blocks, but only if filter does not force them visible. */
if (U.uiflag & USER_HIDE_DOT) {
if ((id->name[2] == '.') && (query[0] != '.')) {
return false;
@@ -485,6 +487,31 @@ static void id_search_cb_objects_from_scene(const bContext *C,
id_search_cb_tagged(C, arg_template, str, items);
}
+static ARegion *template_ID_search_menu_item_tooltip(
+ bContext *C, ARegion *region, const rcti *item_rect, void *arg, void *active)
+{
+ TemplateID *template_ui = arg;
+ ID *active_id = active;
+ StructRNA *type = RNA_property_pointer_type(&template_ui->ptr, template_ui->prop);
+
+ uiSearchItemTooltipData tooltip_data = {0};
+
+ tooltip_data.name = active_id->name + 2;
+ BLI_snprintf(tooltip_data.description,
+ sizeof(tooltip_data.description),
+ TIP_("Choose %s data-block to be assigned to this user"),
+ RNA_struct_ui_name(type));
+ if (ID_IS_LINKED(active_id)) {
+ BLI_snprintf(tooltip_data.hint,
+ sizeof(tooltip_data.hint),
+ TIP_("Source library: %s\n%s"),
+ active_id->lib->id.name + 2,
+ active_id->lib->filepath);
+ }
+
+ return UI_tooltip_create_from_search_item_generic(C, region, item_rect, &tooltip_data);
+}
+
/* ID Search browse menu, open */
static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem)
{
@@ -512,6 +539,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem)
&template_ui,
template_ID_set_property_exec_fn,
active_item_ptr.data,
+ template_ID_search_menu_item_tooltip,
template_ui.prv_rows,
template_ui.prv_cols,
template_ui.scale);
@@ -895,7 +923,7 @@ static void template_ID(const bContext *C,
idfrom = template_ui->ptr.owner_id;
// lb = template_ui->idlb;
- /* Allow opertators to take the ID from context. */
+ /* Allow operators to take the ID from context. */
uiLayoutSetContextPointer(layout, "id", &idptr);
block = uiLayoutGetBlock(layout);
@@ -906,7 +934,7 @@ static void template_ID(const bContext *C,
}
if (text) {
- /* Add label resepecting the separated layout property split state. */
+ /* Add label respecting the separated layout property split state. */
uiItemL_respect_property_split(layout, text, ICON_NONE);
}
@@ -1632,6 +1660,7 @@ static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_tem
&template_search,
template_search_exec_fn,
active_ptr.data,
+ NULL,
template_search.preview_rows,
template_search.preview_cols,
1.0f);
@@ -6802,20 +6831,16 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
width = min_ii((int)(rti->widthfac * width), width);
width = max_ii(width, 10 * UI_DPI_FAC);
- /* make a box around the report to make it stand out */
UI_block_align_begin(block);
- but = uiDefBut(
- block, UI_BTYPE_ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 5, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
- /* set the report's bg color in but->col - UI_BTYPE_ROUNDBOX feature */
- rgba_float_to_uchar(but->col, rti->col);
+ /* Background for icon. */
but = uiDefBut(block,
UI_BTYPE_ROUNDBOX,
0,
"",
- UI_UNIT_X + 5,
0,
- UI_UNIT_X + width,
+ 0,
+ UI_UNIT_X + (6 * UI_DPI_FAC),
UI_UNIT_Y,
NULL,
0.0f,
@@ -6823,46 +6848,57 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
0,
0,
"");
- rgba_float_to_uchar(but->col, rti->col);
+ /* UI_BTYPE_ROUNDBOX's bg color is set in but->col. */
+ UI_GetThemeColorType4ubv(UI_icon_colorid_from_report_type(report->type), SPACE_INFO, but->col);
- UI_block_align_end(block);
+ /* Background for the rest of the message. */
+ but = uiDefBut(block,
+ UI_BTYPE_ROUNDBOX,
+ 0,
+ "",
+ UI_UNIT_X + (6 * UI_DPI_FAC),
+ 0,
+ UI_UNIT_X + width,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0,
+ 0,
+ "");
- /* icon and report message on top */
- const int icon = UI_icon_from_report_type(report->type);
+ /* Use icon background at low opacity to highlight, but still contrasting with area TH_TEXT. */
+ UI_GetThemeColorType4ubv(UI_icon_colorid_from_report_type(report->type), SPACE_INFO, but->col);
+ but->col[3] = 64;
- /* XXX: temporary operator to dump all reports to a text block, but only if more than 1 report
- * to be shown instead of icon when appropriate...
- */
+ UI_block_align_end(block);
UI_block_emboss_set(block, UI_EMBOSS_NONE);
- if (reports->list.first != reports->list.last) {
- uiDefIconButO(block,
- UI_BTYPE_BUT,
- "SCREEN_OT_info_log_show",
- WM_OP_INVOKE_REGION_WIN,
- icon,
- 2,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
- }
- else {
- uiDefIconBut(
- block, UI_BTYPE_LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
- }
+ /* The report icon itself. */
+ but = uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "SCREEN_OT_info_log_show",
+ WM_OP_INVOKE_REGION_WIN,
+ UI_icon_from_report_type(report->type),
+ (3 * UI_DPI_FAC),
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
+ UI_GetThemeColorType4ubv(UI_text_colorid_from_report_type(report->type), SPACE_INFO, but->col);
+ but->col[3] = 255; /* This theme color is RBG only, so have to set alpha here. */
+ /* The report message. */
but = uiDefButO(block,
UI_BTYPE_BUT,
"SCREEN_OT_info_log_show",
WM_OP_INVOKE_REGION_WIN,
report->message,
- UI_UNIT_X + 5,
+ UI_UNIT_X,
0,
- UI_UNIT_X + width,
+ width + UI_UNIT_X,
UI_UNIT_Y,
"Show in Info Log");
- rgba_float_to_uchar(but->col, rti->col);
}
void uiTemplateInputStatus(uiLayout *layout, struct bContext *C)
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 958a0bc03cd..f9eba9eeb6f 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -544,15 +544,74 @@ int UI_icon_from_id(ID *id)
int UI_icon_from_report_type(int type)
{
if (type & RPT_ERROR_ALL) {
- return ICON_ERROR;
+ return ICON_CANCEL;
}
- if (type & RPT_WARNING_ALL) {
+ else if (type & RPT_WARNING_ALL) {
return ICON_ERROR;
}
- if (type & RPT_INFO_ALL) {
+ else if (type & RPT_INFO_ALL) {
return ICON_INFO;
}
- return ICON_NONE;
+ else if (type & RPT_DEBUG_ALL) {
+ return ICON_SYSTEM;
+ }
+ else if (type & RPT_PROPERTY) {
+ return ICON_OPTIONS;
+ }
+ else if (type & RPT_OPERATOR) {
+ return ICON_CHECKMARK;
+ }
+ return ICON_INFO;
+}
+
+int UI_icon_colorid_from_report_type(int type)
+{
+ if (type & RPT_ERROR_ALL) {
+ return TH_INFO_ERROR;
+ }
+ else if (type & RPT_WARNING_ALL) {
+ return TH_INFO_WARNING;
+ }
+ else if (type & RPT_INFO_ALL) {
+ return TH_INFO_INFO;
+ }
+ else if (type & RPT_DEBUG_ALL) {
+ return TH_INFO_DEBUG;
+ }
+ else if (type & RPT_PROPERTY) {
+ return TH_INFO_PROPERTY;
+ }
+ else if (type & RPT_OPERATOR) {
+ return TH_INFO_OPERATOR;
+ }
+ else {
+ return TH_INFO_WARNING;
+ }
+}
+
+int UI_text_colorid_from_report_type(int type)
+{
+ if (type & RPT_ERROR_ALL) {
+ return TH_INFO_ERROR_TEXT;
+ }
+ else if (type & RPT_WARNING_ALL) {
+ return TH_INFO_WARNING_TEXT;
+ }
+ else if (type & RPT_INFO_ALL) {
+ return TH_INFO_INFO_TEXT;
+ }
+ else if (type & RPT_DEBUG_ALL) {
+ return TH_INFO_DEBUG_TEXT;
+ }
+ else if (type & RPT_PROPERTY) {
+ return TH_INFO_PROPERTY_TEXT;
+ }
+ else if (type & RPT_OPERATOR) {
+ return TH_INFO_OPERATOR_TEXT;
+ }
+ else {
+ return TH_INFO_WARNING_TEXT;
+ }
}
/********************************** Misc **************************************/
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 868f62c89c9..5c59d0edeb5 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1311,7 +1311,7 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb,
tria_col[3] = wcol->item[3];
}
- /* Draw everything in one drawcall */
+ /* Draw everything in one draw-call. */
if (inner_col1[3] || inner_col2[3] || outline_col[3] || emboss_col[3] || tria_col[3] ||
show_alpha_checkers) {
widgetbase_set_uniform_colors_ubv(
@@ -1533,25 +1533,22 @@ static void ui_text_clip_right_ex(const uiFontStyle *fstyle,
{
BLI_assert(str[0]);
- /* If the trailing ellipsis takes more than 20% of all available width, just cut the string
- * (as using the ellipsis would remove even more useful chars, and we cannot show much
- * already!).
- */
- if (sep_strwidth / okwidth > 0.2f) {
- float tmp;
- const int l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
- str[l_end] = '\0';
+ /* How many BYTES (not characters) of this utf-8 string can fit, along with appended ellipsis. */
+ int l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, NULL);
+
+ if (l_end > 0) {
+ /* At least one character, so clip and add the ellipsis. */
+ memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
if (r_final_len) {
- *r_final_len = (size_t)l_end;
+ *r_final_len = (size_t)(l_end) + sep_len;
}
}
else {
- float tmp;
- const int l_end = BLF_width_to_strlen(
- fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
- memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
+ /* Otherwise fit as much as we can without adding an ellipsis. */
+ l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, NULL);
+ str[l_end] = '\0';
if (r_final_len) {
- *r_final_len = (size_t)(l_end) + sep_len;
+ *r_final_len = (size_t)l_end;
}
}
}
@@ -2352,7 +2349,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
int icon_size = BLI_rcti_size_y(rect);
int text_size = 0;
- /* This is a bit britle, but avoids adding an 'UI_BUT_HAS_LABEL' flag to but... */
+ /* This is a bit brittle, but avoids adding an 'UI_BUT_HAS_LABEL' flag to but... */
if (icon_size > BLI_rcti_size_x(rect)) {
/* button is not square, it has extra height for label */
text_size = UI_UNIT_Y;
@@ -2413,7 +2410,9 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
rect->xmin += 0.2f * U.widget_unit;
}
- widget_draw_icon(but, icon, alpha, rect, wcol->text);
+ /* By default icon is the color of text, but can optionally override with but->col. */
+ widget_draw_icon(but, icon, alpha, rect, (but->col[3] != 0) ? but->col : wcol->text);
+
if (show_menu_icon) {
BLI_assert(but->block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT);
widget_draw_submenu_tria(but, rect, wcol);
@@ -3617,7 +3616,7 @@ static void widget_scroll(
rect1.xmin = rect1.xmin + ceilf(fac * (value - but->softmin));
rect1.xmax = rect1.xmin + ceilf(fac * (but->a1 - but->softmin));
- /* ensure minimium size */
+ /* Ensure minimum size. */
const float min = BLI_rcti_size_y(rect);
if (BLI_rcti_size_x(&rect1) < min) {
@@ -3634,7 +3633,7 @@ static void widget_scroll(
rect1.ymax = rect1.ymax - ceilf(fac * (value - but->softmin));
rect1.ymin = rect1.ymax - ceilf(fac * (but->a1 - but->softmin));
- /* ensure minimium size */
+ /* Ensure minimum size. */
const float min = BLI_rcti_size_x(rect);
if (BLI_rcti_size_y(&rect1) < min) {
@@ -3671,7 +3670,7 @@ static void widget_progressbar(
const float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog);
float w = value * BLI_rcti_size_x(&rect_prog);
- /* ensure minimium size */
+ /* Ensure minimum size. */
w = MAX2(w, offs);
rect_bar.xmax = rect_bar.xmin + w;
@@ -5224,8 +5223,7 @@ void ui_draw_tooltip_background(const uiStyle *UNUSED(style), uiBlock *UNUSED(bl
*
* \param state: The state of the button,
* typically #UI_ACTIVE, #UI_BUT_DISABLED, #UI_BUT_INACTIVE.
- * \param use_sep: When true, characters after the last #UI_SEP_CHAR are right aligned,
- * use for displaying key shortcuts.
+ * \param separator_type: The kind of separator which controls if and how the string is clipped.
* \param r_xmax: The right hand position of the text, this takes into the icon,
* padding and text clipping when there is not enough room to display the full text.
*/
@@ -5273,7 +5271,7 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + UI_DPI_ICON_SIZE;
}
else if (separator_type == UI_MENU_ITEM_SEPARATOR_HINT) {
- /* Deterimine max-width for the hint string to leave the name string un-clipped (if there's
+ /* Determine max-width for the hint string to leave the name string un-clipped (if there's
* enough space to display it). */
const int available_width = BLI_rcti_size_x(rect) - padding;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f115618c13b..59aee0fde29 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1895,7 +1895,7 @@ void UI_view2d_scroller_size_get(const View2D *v2d, float *r_x, float *r_y)
*
* \param r_x, r_y: scale on each axis
*/
-void UI_view2d_scale_get(View2D *v2d, float *r_x, float *r_y)
+void UI_view2d_scale_get(const View2D *v2d, float *r_x, float *r_y)
{
if (r_x) {
*r_x = UI_view2d_scale_get_x(v2d);
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 222f03ee1d8..e234ab5dcdc 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -46,7 +46,7 @@
#include "UI_interface.h"
#include "UI_view2d.h"
-#include "PIL_time.h" /* USER_ZOOM_CONT */
+#include "PIL_time.h" /* USER_ZOOM_CONTINUE */
/* -------------------------------------------------------------------- */
/** \name Internal Utilities
@@ -1106,14 +1106,9 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
float dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac;
float dy = RNA_float_get(op->ptr, "deltay") / U.dpi_fac;
- if (U.uiflag & USER_ZOOM_INVERT) {
- dx *= -1;
- dy *= -1;
- }
-
/* Check if the 'timer' is initialized, as zooming with the trackpad
* never uses the "Continuous" zoom method, and the 'timer' is not initialized. */
- if ((U.viewzoom == USER_ZOOM_CONT) && vzd->timer) { /* XXX store this setting as RNA prop? */
+ 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);
@@ -1232,26 +1227,53 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
vzd->lastx = event->prevx;
vzd->lasty = event->prevy;
- /* As we have only 1D information (magnify value), feed both axes
- * with magnify information that is stored in x axis
- */
- float fac = 0.01f * (event->prevx - event->x);
- float dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f;
+ float facx, facy;
+ float zoomfac = 0.01f;
+
+ /* Some view2d's (graph) don't have min/max zoom, or extreme ones. */
+ if (v2d->maxzoom > 0.0f) {
+ zoomfac = clamp_f(0.001f * v2d->maxzoom, 0.001f, 0.01f);
+ }
+
if (event->type == MOUSEPAN) {
- fac = 0.01f * (event->prevy - event->y);
+ facx = zoomfac * WM_event_absolute_delta_x(event);
+ facy = zoomfac * WM_event_absolute_delta_y(event);
+
+ if (U.uiflag & USER_ZOOM_INVERT) {
+ facx *= -1.0f;
+ facy *= -1.0f;
+ }
+ }
+ else { /* MOUSEZOOM */
+ facx = facy = zoomfac * WM_event_absolute_delta_x(event);
+ }
+
+ /* Only respect user setting zoom axis if the view does not have any zoom restrictions
+ * any will be scaled uniformly. */
+ if (((v2d->keepzoom & (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y)) == 0) &&
+ (v2d->keepzoom & V2D_KEEPASPECT)) {
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ facy = 0.0f;
+ }
+ else {
+ facx = 0.0f;
+ }
}
- float dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f;
/* support trackpad zoom to always zoom entirely - the v2d code uses portrait or
* landscape exceptions */
if (v2d->keepzoom & V2D_KEEPASPECT) {
- if (fabsf(dx) > fabsf(dy)) {
- dy = dx;
+ if (fabsf(facx) > fabsf(facy)) {
+ facy = facx;
}
else {
- dx = dy;
+ facx = facy;
}
}
+
+ const float dx = facx * BLI_rctf_size_x(&v2d->cur);
+ const float dy = facy * BLI_rctf_size_y(&v2d->cur);
+
RNA_float_set(op->ptr, "deltax", dx);
RNA_float_set(op->ptr, "deltay", dy);
@@ -1282,7 +1304,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
/* add temp handler */
WM_event_add_modal_handler(C, op);
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vzd->timer = WM_event_add_timer(CTX_wm_manager(C), window, TIMER, 0.01f);
vzd->timer_lastdraw = PIL_check_seconds_timer();
@@ -1320,19 +1342,13 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event
/* x-axis transform */
dist = BLI_rcti_size_x(&v2d->mask) / 2.0f;
- len_old[0] = fabsf(vzd->lastx - vzd->region->winrct.xmin - dist);
- len_new[0] = fabsf(event->x - vzd->region->winrct.xmin - dist);
-
- len_old[0] *= zoomfac * BLI_rctf_size_x(&v2d->cur);
- len_new[0] *= zoomfac * BLI_rctf_size_x(&v2d->cur);
+ len_old[0] = zoomfac * fabsf(vzd->lastx - vzd->region->winrct.xmin - dist);
+ len_new[0] = zoomfac * fabsf(event->x - vzd->region->winrct.xmin - dist);
/* y-axis transform */
dist = BLI_rcti_size_y(&v2d->mask) / 2.0f;
- len_old[1] = fabsf(vzd->lasty - vzd->region->winrct.ymin - dist);
- len_new[1] = fabsf(event->y - vzd->region->winrct.ymin - dist);
-
- len_old[1] *= zoomfac * BLI_rctf_size_y(&v2d->cur);
- len_new[1] *= zoomfac * BLI_rctf_size_y(&v2d->cur);
+ len_old[1] = zoomfac * fabsf(vzd->lasty - vzd->region->winrct.ymin - dist);
+ len_new[1] = zoomfac * fabsf(event->y - vzd->region->winrct.ymin - dist);
/* Calculate distance */
if (v2d->keepzoom & V2D_KEEPASPECT) {
@@ -1343,40 +1359,44 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event
dx = len_new[0] - len_old[0];
dy = len_new[1] - len_old[1];
}
- }
- else {
- /* 'continuous' or 'dolly' */
- float fac;
- /* x-axis transform */
- fac = zoomfac * (event->x - vzd->lastx);
- dx = fac * BLI_rctf_size_x(&v2d->cur);
- /* y-axis transform */
- fac = zoomfac * (event->y - vzd->lasty);
- dy = fac * BLI_rctf_size_y(&v2d->cur);
+ dx *= BLI_rctf_size_x(&v2d->cur);
+ dy *= BLI_rctf_size_y(&v2d->cur);
+ }
+ else { /* USER_ZOOM_CONTINUE or USER_ZOOM_DOLLY */
+ float facx = zoomfac * (event->x - vzd->lastx);
+ float facy = zoomfac * (event->y - vzd->lasty);
/* Only respect user setting zoom axis if the view does not have any zoom restrictions
* any will be scaled uniformly */
if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 && (v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 &&
(v2d->keepzoom & V2D_KEEPASPECT)) {
if (U.uiflag & USER_ZOOM_HORIZ) {
- dy = 0;
+ facy = 0.0f;
}
else {
- dx = 0;
+ facx = 0.0f;
}
}
- }
- /* support zoom to always zoom entirely - the v2d code uses portrait or
- * landscape exceptions */
- if (v2d->keepzoom & V2D_KEEPASPECT) {
- if (fabsf(dx) > fabsf(dy)) {
- dy = dx;
- }
- else {
- dx = dy;
+ /* support zoom to always zoom entirely - the v2d code uses portrait or
+ * landscape exceptions */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ if (fabsf(facx) > fabsf(facy)) {
+ facy = facx;
+ }
+ else {
+ facx = facy;
+ }
}
+
+ dx = facx * BLI_rctf_size_x(&v2d->cur);
+ dy = facy * BLI_rctf_size_y(&v2d->cur);
+ }
+
+ if (U.uiflag & USER_ZOOM_INVERT) {
+ dx *= -1.0f;
+ dy *= -1.0f;
}
/* set transform amount, and add current deltas to stored total delta (for redo) */
@@ -1390,7 +1410,7 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event
* - Continuous zoom only depends on distance of mouse
* to starting point to determine rate of change.
*/
- if (U.viewzoom != USER_ZOOM_CONT) { /* XXX store this setting as RNA prop? */
+ if (U.viewzoom != USER_ZOOM_CONTINUE) { /* XXX store this setting as RNA prop? */
vzd->lastx = event->x;
vzd->lasty = event->y;
}
@@ -2204,7 +2224,7 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *
scroller_activate_init(C, op, event, in_scroller);
v2dScrollerMove *vsm = (v2dScrollerMove *)op->customdata;
- /* support for quick jump to location - gtk and qt do this on linux */
+ /* Support for quick jump to location - GTK and QT do this on Linux. */
if (event->type == MIDDLEMOUSE) {
switch (vsm->scroller) {
case 'h': /* horizontal scroller - so only horizontal movement
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 636e6688971..a66f53ea839 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -35,19 +35,16 @@
# include "MEM_guardedalloc.h"
-# include "DNA_mesh_types.h"
# include "DNA_modifier_types.h"
# include "DNA_object_types.h"
# include "DNA_scene_types.h"
# include "DNA_space_types.h"
# include "BKE_context.h"
-# include "BKE_global.h"
# include "BKE_main.h"
# include "BKE_report.h"
# include "BLI_listbase.h"
-# include "BLI_math_vector.h"
# include "BLI_path_util.h"
# include "BLI_string.h"
# include "BLI_utildefines.h"
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index b73b8abccfe..1e66a86c8fd 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -26,7 +26,6 @@
#include "DNA_cachefile_types.h"
#include "DNA_space_types.h"
-#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 200786ca99d..2bf975cc4f5 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -29,7 +29,6 @@
# include "BLI_utildefines.h"
# include "BKE_context.h"
-# include "BKE_global.h"
# include "BKE_main.h"
# include "BKE_object.h"
# include "BKE_report.h"
@@ -37,7 +36,6 @@
# include "DEG_depsgraph.h"
# include "ED_object.h"
-# include "ED_screen.h"
# include "RNA_access.h"
# include "RNA_define.h"
diff --git a/source/blender/editors/lattice/editlattice_select.c b/source/blender/editors/lattice/editlattice_select.c
index 4497ca1a379..cb3f9a89e62 100644
--- a/source/blender/editors/lattice/editlattice_select.c
+++ b/source/blender/editors/lattice/editlattice_select.c
@@ -108,7 +108,7 @@ bool ED_lattice_deselect_all_multi(struct bContext *C)
static int lattice_select_random_exec(bContext *C, wmOperator *op)
{
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c
index 3a5734706f1..3ffbc3712fc 100644
--- a/source/blender/editors/lattice/editlattice_undo.c
+++ b/source/blender/editors/lattice/editlattice_undo.c
@@ -212,8 +212,11 @@ static bool lattice_undosys_step_encode(struct bContext *C, Main *bmain, UndoSte
return true;
}
-static void lattice_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void lattice_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
LatticeUndoStep *us = (LatticeUndoStep *)us_p;
diff --git a/source/blender/editors/lattice/lattice_ops.c b/source/blender/editors/lattice/lattice_ops.c
index d5505c00132..3f96b8a303b 100644
--- a/source/blender/editors/lattice/lattice_ops.c
+++ b/source/blender/editors/lattice/lattice_ops.c
@@ -23,15 +23,10 @@
#include "DNA_scene_types.h"
-#include "RNA_access.h"
-
#include "WM_api.h"
-#include "WM_types.h"
#include "ED_lattice.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "lattice_intern.h"
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index d7b3d74bc7e..1226cc57359 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -507,6 +507,9 @@ static int add_vertex_handle_cyclic(
static int add_vertex_exec(bContext *C, wmOperator *op)
{
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
Mask *mask = CTX_data_edit_mask(C);
if (mask == NULL) {
/* if there's no active mask, create one */
@@ -548,6 +551,8 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
@@ -690,6 +695,9 @@ void MASK_OT_add_feather_vertex(wmOperatorType *ot)
static int create_primitive_from_points(
bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type)
{
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
ScrArea *area = CTX_wm_area(C);
int size = RNA_float_get(op->ptr, "size");
@@ -752,6 +760,8 @@ static int create_primitive_from_points(
DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 89fd2fa9b62..d3fa0e93597 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -539,7 +539,7 @@ static void draw_spline_curve(const bContext *C,
uint tot_feather_point;
float(*feather_points)[2];
- diff_points = BKE_mask_spline_differentiate_with_resolution(spline, &tot_diff_point, resol);
+ diff_points = BKE_mask_spline_differentiate_with_resolution(spline, resol, &tot_diff_point);
if (!diff_points) {
return;
@@ -550,7 +550,7 @@ static void draw_spline_curve(const bContext *C,
}
feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(
- spline, &tot_feather_point, resol, (is_fill != false));
+ spline, resol, (is_fill != false), &tot_feather_point);
/* draw feather */
mask_spline_feather_color_get(mask_layer, spline, is_spline_sel, rgb_tmp);
diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c
index 663ae0097ad..f1041d062a8 100644
--- a/source/blender/editors/mask/mask_edit.c
+++ b/source/blender/editors/mask/mask_edit.c
@@ -184,3 +184,39 @@ void ED_operatormacros_mask(void)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Lock-to-selection viewport preservation
+ * \{ */
+
+void ED_mask_view_lock_state_store(const bContext *C, MaskViewLockState *state)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ if (space_clip != NULL) {
+ ED_clip_view_lock_state_store(C, &state->space_clip_state);
+ }
+}
+
+void ED_mask_view_lock_state_restore_no_jump(const bContext *C, const MaskViewLockState *state)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ if (space_clip != NULL) {
+ if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
+ /* Early output if the editor is not locked to selection.
+ * Avoids forced dependency graph evaluation here. */
+ return;
+ }
+
+ /* Mask's lock-to-selection requires deformed splines to be evaluated to calculate bounds of
+ * points after animation has been evaluated. The restore-no-jump type of function does
+ * calculation of new offset for the view for an updated state of mask to cancel the offset out
+ * by modifying locked offset. In order to do such calculation mask needs to be evaluated after
+ * modification by an operator. */
+ struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ (void)depsgraph;
+
+ ED_clip_view_lock_state_restore_no_jump(C, &state->space_clip_state);
+ }
+}
+
+/** \} */
diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h
index f6990583383..ee1784011ea 100644
--- a/source/blender/editors/mask/mask_intern.h
+++ b/source/blender/editors/mask/mask_intern.h
@@ -23,6 +23,8 @@
#pragma once
+#include "ED_clip.h"
+
struct Mask;
struct bContext;
struct wmOperatorType;
@@ -92,6 +94,19 @@ void ED_mask_select_flush_all(struct Mask *mask);
bool ED_maskedit_poll(struct bContext *C);
bool ED_maskedit_mask_poll(struct bContext *C);
+/* Generalized solution for preserving editor viewport when making changes while lock-to-selection
+ * is enabled.
+ * Any mask operator can use this API, without worrying that some editors do not have an idea of
+ * lock-to-selection. */
+
+typedef struct MaskViewLockState {
+ ClipViewLockState space_clip_state;
+} MaskViewLockState;
+
+void ED_mask_view_lock_state_store(const struct bContext *C, MaskViewLockState *state);
+void ED_mask_view_lock_state_restore_no_jump(const struct bContext *C,
+ const MaskViewLockState *state);
+
/* mask_query.c */
bool ED_mask_find_nearest_diff_point(const struct bContext *C,
struct Mask *mask,
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 25cc39bf9a0..14f81520b9a 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -226,13 +226,19 @@ typedef struct SlidePointData {
int width, height;
float prev_mouse_coord[2];
+
+ /* Previous clip coordinate which was resolved from mouse position (0, 0).
+ * Is used to compensate for view offset moving in-between of mouse events when
+ * lock-to-selection is enabled. */
+ float prev_zero_coord[2];
+
float no[2];
bool is_curvature_only, is_accurate, is_initial_feather, is_overall_feather;
bool is_sliding_new_point;
- /* Data needed to restre the state. */
+ /* Data needed to restore the state. */
float vec[3][3];
char old_h1, old_h2;
@@ -431,6 +437,9 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
const float threshold = 19;
eMaskWhichHandle which_handle;
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
ED_mask_mouse_pos(area, region, event->mval, co);
ED_mask_get_size(area, &width, &height);
@@ -530,7 +539,15 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
}
customdata->which_handle = which_handle;
+ {
+ WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
+ DEG_id_tag_update(&mask->id, 0);
+
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+ }
+
ED_mask_mouse_pos(area, region, event->mval, customdata->prev_mouse_coord);
+ ED_mask_mouse_pos(area, region, (int[2]){0, 0}, customdata->prev_zero_coord);
}
return customdata;
@@ -655,10 +672,24 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
ED_mask_mouse_pos(area, region, event->mval, co);
sub_v2_v2v2(delta, co, data->prev_mouse_coord);
+ copy_v2_v2(data->prev_mouse_coord, co);
+
+ /* Compensate for possibly moved view offset since the last event.
+ * The idea is to see how mapping of a fixed and known position did change. */
+ {
+ float zero_coord[2];
+ ED_mask_mouse_pos(area, region, (int[2]){0, 0}, zero_coord);
+
+ float zero_delta[2];
+ sub_v2_v2v2(zero_delta, zero_coord, data->prev_zero_coord);
+ sub_v2_v2(delta, zero_delta);
+
+ copy_v2_v2(data->prev_zero_coord, zero_coord);
+ }
+
if (data->is_accurate) {
mul_v2_fl(delta, 0.2f);
}
- copy_v2_v2(data->prev_mouse_coord, co);
if (data->action == SLIDE_ACTION_HANDLE) {
float new_handle[2];
@@ -832,7 +863,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == data->event_invoke_type && event->val == KM_RELEASE) {
Scene *scene = CTX_data_scene(C);
- /* dont key sliding feather uw's */
+ /* Don't key sliding feather UW's. */
if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == false) {
if (IS_AUTOKEY_ON(scene)) {
ED_mask_layer_shape_auto_key(data->mask_layer, CFRA);
@@ -966,6 +997,9 @@ static SlideSplineCurvatureData *slide_spline_curvature_customdata(bContext *C,
float u, co[2];
BezTriple *next_bezt;
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
ED_mask_mouse_pos(CTX_wm_area(C), CTX_wm_region(C), event->mval, co);
if (!ED_mask_find_nearest_diff_point(C,
@@ -1019,7 +1053,7 @@ static SlideSplineCurvatureData *slide_spline_curvature_customdata(bContext *C,
slide_data->bezt_backup = *slide_data->adjust_bezt;
slide_data->other_bezt_backup = *slide_data->other_bezt;
- /* Let's dont touch other side of the point for now, so set handle to FREE. */
+ /* Let's don't touch other side of the point for now, so set handle to FREE. */
if (u < 0.5f) {
if (slide_data->adjust_bezt->h2 <= HD_VECT) {
slide_data->adjust_bezt->h2 = HD_FREE;
@@ -1047,6 +1081,9 @@ static SlideSplineCurvatureData *slide_spline_curvature_customdata(bContext *C,
mask_layer->act_point = point;
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, 0);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return slide_data;
}
@@ -1233,7 +1270,7 @@ static int slide_spline_curvature_modal(bContext *C, wmOperator *op, const wmEve
case LEFTMOUSE:
case RIGHTMOUSE:
if (event->type == slide_data->event_invoke_type && event->val == KM_RELEASE) {
- /* dont key sliding feather uw's */
+ /* Don't key sliding feather UW's. */
if (IS_AUTOKEY_ON(scene)) {
ED_mask_layer_shape_auto_key(slide_data->mask_layer, CFRA);
}
diff --git a/source/blender/editors/mask/mask_query.c b/source/blender/editors/mask/mask_query.c
index cfd57ca3477..401b6eac4f2 100644
--- a/source/blender/editors/mask/mask_query.c
+++ b/source/blender/editors/mask/mask_query.c
@@ -604,22 +604,37 @@ void ED_mask_point_pos__reverse(
*yr = co[1];
}
-bool ED_mask_selected_minmax(const bContext *C, float min[2], float max[2])
+static void handle_position_for_minmax(const MaskSplinePoint *point,
+ eMaskWhichHandle which_handle,
+ bool handles_as_control_point,
+ float r_handle[2])
+{
+ if (handles_as_control_point) {
+ copy_v2_v2(r_handle, point->bezt.vec[1]);
+ return;
+ }
+ BKE_mask_point_handle(point, which_handle, r_handle);
+}
+
+bool ED_mask_selected_minmax(const bContext *C,
+ float min[2],
+ float max[2],
+ bool handles_as_control_point)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Mask *mask = CTX_data_edit_mask(C);
- /* Use evaluated mask to take animation into account.
- * The animation of splies is not "flushed" back to original, so need to explicitly
- * sue evaluated datablock here. */
- Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask->id);
-
bool ok = false;
if (mask == NULL) {
return ok;
}
+ /* Use evaluated mask to take animation into account.
+ * The animation of splies is not "flushed" back to original, so need to explicitly
+ * sue evaluated datablock here. */
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask->id);
+
INIT_MINMAX2(min, max);
for (MaskLayer *mask_layer = mask_eval->masklayers.first; mask_layer != NULL;
mask_layer = mask_layer->next) {
@@ -638,22 +653,29 @@ bool ED_mask_selected_minmax(const bContext *C, float min[2], float max[2])
}
if (bezt->f2 & SELECT) {
minmax_v2v2_v2(min, max, deform_point->bezt.vec[1]);
+ ok = true;
}
+
if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_STICK, handle);
+ handle_position_for_minmax(
+ deform_point, MASK_WHICH_HANDLE_STICK, handles_as_control_point, handle);
minmax_v2v2_v2(min, max, handle);
+ ok = true;
}
else {
if ((bezt->f1 & SELECT) && (bezt->h1 != HD_VECT)) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_LEFT, handle);
+ handle_position_for_minmax(
+ deform_point, MASK_WHICH_HANDLE_LEFT, handles_as_control_point, handle);
minmax_v2v2_v2(min, max, handle);
+ ok = true;
}
if ((bezt->f3 & SELECT) && (bezt->h2 != HD_VECT)) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_RIGHT, handle);
+ handle_position_for_minmax(
+ deform_point, MASK_WHICH_HANDLE_RIGHT, handles_as_control_point, handle);
minmax_v2v2_v2(min, max, handle);
+ ok = true;
}
}
- ok = true;
}
}
}
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index cdc6ece1e84..5c369afc4cd 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -214,12 +214,17 @@ static int select_all_exec(bContext *C, wmOperator *op)
Mask *mask = CTX_data_edit_mask(C);
int action = RNA_enum_get(op->ptr, "action");
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
ED_mask_select_toggle_all(mask, action);
ED_mask_select_flush_all(mask);
DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
@@ -261,6 +266,9 @@ static int select_exec(bContext *C, wmOperator *op)
eMaskWhichHandle which_handle;
const float threshold = 19;
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
RNA_float_get_array(op->ptr, "location", co);
point = ED_mask_point_find_nearest(
@@ -324,6 +332,8 @@ static int select_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
@@ -364,12 +374,15 @@ static int select_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
if (deselect_all) {
/* For clip editor tracks, leave deselect all to clip editor. */
if (!ED_clip_can_select(C)) {
ED_mask_deselect_all(C);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
return OPERATOR_FINISHED;
}
}
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index a5dd29c9d73..d60d83850a5 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -24,7 +24,6 @@
#include "BLI_math.h"
#include "BLI_sys_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -42,7 +41,6 @@
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_uvedit.h"
#include "mesh_intern.h" /* own include */
diff --git a/source/blender/editors/mesh/editmesh_automerge.c b/source/blender/editors/mesh/editmesh_automerge.c
index f9910f01f47..2bd5b9b26ca 100644
--- a/source/blender/editors/mesh/editmesh_automerge.c
+++ b/source/blender/editors/mesh/editmesh_automerge.c
@@ -26,12 +26,9 @@
* - #EDBM_automerge_and_split
*/
-#include "MEM_guardedalloc.h"
-
#include "BKE_editmesh.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
#include "ED_mesh.h"
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 8ea3c883433..66a7b97b440 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -28,11 +28,9 @@
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_curveprofile.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_layer.h"
-#include "BKE_mesh.h"
#include "BKE_unit.h"
#include "DNA_curveprofile_types.h"
@@ -575,7 +573,7 @@ static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
opdata->shift_value[vmode] = -1.0f;
}
- /* clamp accordingto value mode, and store value back */
+ /* Clamp according to value mode, and store value back. */
CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
if (vmode == SEGMENTS_VALUE) {
opdata->segments = value;
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c
index 7b3fabf07fc..187652ae00f 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin.c
@@ -33,17 +33,13 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
-#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "UI_resources.h"
-
#include "MEM_guardedalloc.h"
#include "mesh_intern.h" /* own include */
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index f45f48e0e32..1f894ec0f1d 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -210,7 +210,7 @@ typedef struct KnifeTool_OpData {
/* run by the UI or not */
bool is_interactive;
- /* operatpr options */
+ /* Operator options. */
bool cut_through; /* preference, can be modified at runtime (that feature may go) */
bool only_select; /* set on initialization */
bool select_result; /* set on initialization */
@@ -2752,8 +2752,6 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
}
- view3d_operator_needs_opengl(C);
-
/* alloc new customdata */
kcd = op->customdata = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
@@ -2831,7 +2829,6 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
em_setup_viewcontext(C, &kcd->vc);
kcd->region = kcd->vc.region;
- view3d_operator_needs_opengl(C);
ED_view3d_init_mats_rv3d(obedit, kcd->vc.rv3d); /* needed to initialize clipping */
if (kcd->mode == MODE_PANNING) {
@@ -3067,8 +3064,6 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
{
KnifeTool_OpData *kcd;
- view3d_operator_needs_opengl(C);
-
/* init */
{
const bool only_select = false;
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index 3e0bee3c4b8..7d849c096e7 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -81,7 +81,7 @@ typedef struct GeometryExtactParams {
/* For extracting Mask. */
float mask_threshold;
- /* Common paramenters. */
+ /* Common parameters. */
bool add_boundary_loop;
int num_smooth_iterations;
bool apply_shrinkwrap;
@@ -106,7 +106,7 @@ static int geometry_extract_apply(bContext *C,
BKE_sculpt_mask_layers_ensure(ob, NULL);
- /* Ensures that deformation from sculpt mode is taken into accunt before duplicating the mesh to
+ /* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to
* extract the geometry. */
CTX_data_ensure_evaluated_depsgraph(C);
@@ -385,7 +385,7 @@ static int face_set_extract_modal(bContext *C, wmOperator *op, const wmEvent *ev
ED_workspace_status_text(C, NULL);
/* This modal operator uses and eyedropper to pick a Face Set from the mesh. This ensures
- * that the mouse clicked in a viewport region and its coordinates can be used to raycast
+ * that the mouse clicked in a viewport region and its coordinates can be used to ray-cast
* the PBVH and update the active Face Set ID. */
bScreen *screen = CTX_wm_screen(C);
ARegion *region = BKE_screen_find_main_region_at_xy(
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index b5b4802aa78..c8449644dd0 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -2205,7 +2205,7 @@ void EDBM_selectmode_set(BMEditMesh *em)
}
}
else if (em->selectmode & SCE_SELECT_FACE) {
- /* deselect eges, and select again based on face select */
+ /* Deselect edges, and select again based on face select. */
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
BM_edge_select_set(em->bm, eed, false);
}
@@ -2247,7 +2247,7 @@ void EDBM_selectmode_convert(BMEditMesh *em,
/* first tag-to-select, then select --- this avoids a feedback loop */
- /* have to find out what the selectionmode was previously */
+ /* Have to find out what the selection-mode was previously. */
if (selectmode_old == SCE_SELECT_VERTEX) {
if (bm->totvertsel == 0) {
/* pass */
@@ -4573,7 +4573,7 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
static int edbm_select_random_exec(bContext *C, wmOperator *op)
{
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
ViewLayer *view_layer = CTX_data_view_layer(C);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 84f4e35cb0c..de37ddec885 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -3905,7 +3905,7 @@ static float bm_edge_seg_isect(const float sco_a[2],
x12 = mouse_path[i][0];
y12 = mouse_path[i][1];
- /* Perp. Distance from point to line */
+ /* Calculate the distance from point to line. */
if (m2 != MAXSLOPE) {
/* sqrt(m2 * m2 + 1); Only looking for change in sign. Skip extra math .*/
dist = (y12 - m2 * x12 - b2);
@@ -4010,7 +4010,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
short numcuts = 1;
const short mode = RNA_int_get(op->ptr, "type");
- /* allocd vars */
+ /* Allocated variables. */
float(*screen_vert_coords)[2], (*sco)[2], (*mouse_path)[2];
/* edit-object needed for matrix, and region->regiondata for projections to work */
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 41bb3faa135..dd51d63961c 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -188,7 +188,7 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
else {
bcd_reference_current = NULL;
- /* do a full lookup when un-alligned */
+ /* Do a full lookup when unaligned. */
if (bcd_reference) {
const BArrayCustomData *bcd_iter = bcd_reference;
while (bcd_iter) {
@@ -766,8 +766,11 @@ 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, int UNUSED(dir), bool UNUSED(is_final))
+static void mesh_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
MeshUndoStep *us = (MeshUndoStep *)us_p;
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 2cf97b7235f..27d73497b49 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -21,7 +21,6 @@
* \ingroup edmesh
*/
-#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "RNA_access.h"
@@ -30,9 +29,7 @@
#include "WM_types.h"
#include "ED_mesh.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "mesh_intern.h" /* own include */
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 3b5897de0b0..3450d61337c 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -145,7 +145,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
if (ob_src != ob_dst) {
float cmat[4][4];
- /* watch this: switch matmul order really goes wrong */
+ /* Watch this: switch matrix multiplication order really goes wrong. */
mul_m4_m4m4(cmat, imat, ob_src->obmat);
/* transform vertex coordinates into new space */
@@ -733,7 +733,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
BKE_key_sort(key);
}
- /* Due to dependnecy cycle some other object might access old derived data. */
+ /* Due to dependency cycle some other object might access old derived data. */
BKE_object_free_derived_caches(ob);
DEG_relations_tag_update(bmain); /* removed objects, need to rebuild dag */
diff --git a/source/blender/editors/metaball/editmball_undo.c b/source/blender/editors/metaball/editmball_undo.c
index cbc60bcc031..b817bc3a718 100644
--- a/source/blender/editors/metaball/editmball_undo.c
+++ b/source/blender/editors/metaball/editmball_undo.c
@@ -187,8 +187,11 @@ static bool mball_undosys_step_encode(struct bContext *C, struct Main *bmain, Un
return true;
}
-static void mball_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void mball_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
MBallUndoStep *us = (MBallUndoStep *)us_p;
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 094011ebef1..cf453bf0c32 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -483,7 +483,7 @@ void MBALL_OT_select_similar(wmOperatorType *ot)
static int select_random_metaelems_exec(bContext *C, wmOperator *op)
{
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
ViewLayer *view_layer = CTX_data_view_layer(C);
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index 100ca4691ca..a54ec384d8e 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -29,9 +29,7 @@
#include "WM_types.h"
#include "ED_mball.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "mball_intern.h"
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index c6d6b8b16b9..b6b6dcfaa59 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -516,7 +516,7 @@ bool ED_object_add_generic_get_opts(bContext *C,
if (RNA_struct_property_is_set(op->ptr, "rotation")) {
/* If rotation is set, always use it. Alignment (and corresponding user preference)
* can be ignored since this is in world space anyways.
- * To not confuse (e.g. on redo), dont set it to ALIGN_WORLD in the op UI though. */
+ * To not confuse (e.g. on redo), don't set it to #ALIGN_WORLD in the op UI though. */
*is_view_aligned = false;
RNA_float_get_array(op->ptr, "rotation", rot);
}
@@ -607,7 +607,6 @@ Object *ED_object_add_type_with_obdata(bContext *C,
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- /* For as long scene has editmode... */
{
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
if (obedit != NULL) {
@@ -1712,9 +1711,8 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_add_type(C, OB_SPEAKER, NULL, loc, rot, false, local_view_bits);
const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ob);
- /* to make it easier to start using this immediately in NLA, a default sound clip is created
- * ready to be moved around to retime the sound and/or make new sound clips
- */
+ /* To make it easier to start using this immediately in NLA, a default sound clip is created
+ * ready to be moved around to re-time the sound and/or make new sound clips. */
{
/* create new data for NLA hierarchy */
AnimData *adt = BKE_animdata_add_id(&ob->id);
@@ -3364,6 +3362,9 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
ED_view3d_cursor3d_position(C, mval, false, basen->object->loc);
}
+ /* 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, NULL, BA_DESELECT);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_activate(C, basen);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index db9e51a490d..b1ba856ff0f 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -1339,7 +1339,7 @@ static int bake(const BakeAPIRender *bkr,
highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER);
highpoly[i].me = BKE_mesh_new_from_object(NULL, highpoly[i].ob_eval, false);
- /* lowpoly to highpoly transformation matrix */
+ /* Low-poly to high-poly transformation matrix. */
copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 4cbb8858bf4..b251e617a4c 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -51,8 +51,6 @@
#include "ED_object.h"
-#include "UI_interface.h"
-
#include "object_intern.h"
/* All possible data to transfer.
@@ -65,7 +63,7 @@ static const EnumPropertyItem DT_layer_items[] = {
0,
"Vertex Group(s)",
"Transfer active or all vertex groups"},
-#if 0 /* XXX For now, would like to finish/merge work from 2014 gsoc first. */
+#if 0 /* XXX For now, would like to finish/merge work from 2014 GSOC first. */
{DT_TYPE_SHAPEKEY, "SHAPEKEYS", 0, "Shapekey(s)", "Transfer active or all shape keys"},
#endif
/* XXX When SkinModifier is enabled,
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 6350ffb9c77..7e0e52d3874 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -3024,7 +3024,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
i++;
}
- /* make a copy of ocean to use for baking - threadsafety */
+ /* Make a copy of ocean to use for baking - thread-safety. */
struct Ocean *ocean = BKE_ocean_add();
BKE_ocean_init_from_modifier(ocean, omd, omd->resolution);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 964d9898ac0..2124d242ee2 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -25,23 +25,15 @@
#include <stdlib.h>
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
-#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_select_utils.h"
-
-#include "DEG_depsgraph.h"
#include "object_intern.h"
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index acad1b43cbb..5a2ef1c6556 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1790,20 +1790,33 @@ void OBJECT_OT_make_links_scene(wmOperatorType *ot)
void OBJECT_OT_make_links_data(wmOperatorType *ot)
{
static const EnumPropertyItem make_links_items[] = {
- {MAKE_LINKS_OBDATA, "OBDATA", 0, "Object Data", ""},
- {MAKE_LINKS_MATERIALS, "MATERIAL", 0, "Materials", ""},
- {MAKE_LINKS_ANIMDATA, "ANIMATION", 0, "Animation Data", ""},
- {MAKE_LINKS_GROUP, "GROUPS", 0, "Collection", ""},
- {MAKE_LINKS_DUPLICOLLECTION, "DUPLICOLLECTION", 0, "Instance Collection", ""},
- {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Modifiers", ""},
- {MAKE_LINKS_FONTS, "FONTS", 0, "Fonts", ""},
- {MAKE_LINKS_SHADERFX, "EFFECTS", 0, "Effects", ""},
+ {MAKE_LINKS_OBDATA, "OBDATA", 0, "Link Object Data", "Replace assigned Object Data"},
+ {MAKE_LINKS_MATERIALS, "MATERIAL", 0, "Link Materials", "Replace assigned Materials"},
+ {MAKE_LINKS_ANIMDATA,
+ "ANIMATION",
+ 0,
+ "Link Animation Data",
+ "Replace assigned Animation Data"},
+ {MAKE_LINKS_GROUP, "GROUPS", 0, "Link Collections", "Replace assigned Collections"},
+ {MAKE_LINKS_DUPLICOLLECTION,
+ "DUPLICOLLECTION",
+ 0,
+ "Link Instance Collection",
+ "Replace assigned Collection Instance"},
+ {MAKE_LINKS_FONTS, "FONTS", 0, "Link Fonts to Text", "Replace Text object Fonts"},
+ {0, "", 0, NULL, NULL},
+ {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Copy Modifiers", "Replace Modifiers"},
+ {MAKE_LINKS_SHADERFX,
+ "EFFECTS",
+ 0,
+ "Copy Grease Pencil Effects",
+ "Replace Grease Pencil Effects"},
{0, NULL, 0, NULL, NULL},
};
/* identifiers */
- ot->name = "Link Data";
- ot->description = "Apply active object links to other selected objects";
+ ot->name = "Link/Transfer Data";
+ ot->description = "Transfer data from active object to selected objects";
ot->idname = "OBJECT_OT_make_links_data";
/* api callbacks */
@@ -2328,7 +2341,7 @@ void OBJECT_OT_make_local(wmOperatorType *ot)
static bool make_override_library_object_overridable_check(Main *bmain, Object *object)
{
- /* An object is actually overrideable only if it is in at least one local collections.
+ /* An object is actually overridable only if it is in at least one local collection.
* Unfortunately 'direct link' flag is not enough here. */
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
if (!ID_IS_LINKED(collection) && BKE_collection_has_object(collection, object)) {
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index d560d347217..f55ce88b426 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -327,7 +327,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar),
const float total_len = len_v3v3(cd->preview_plane[0], cd->preview_plane[1]);
const int tot_lines = (int)(total_len / cd->voxel_size);
- /* Smoothstep to reduce the alpha of the grid as the line number increases. */
+ /* 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;
const float b = VOXEL_SIZE_EDIT_MAX_GRIDS_LINES;
const float x = clamp_f((tot_lines - a) / (b - a), 0.0f, 1.0);
@@ -738,7 +738,7 @@ static int quadriflow_break_job(void *customdata)
return should_break;
}
-/* called by oceanbake, wmJob sends notifier */
+/** Called by ocean-bake, #wmJob sends notifier. */
static void quadriflow_update_job(void *customdata, float progress, int *cancel)
{
QuadriFlowJob *qj = customdata;
@@ -982,7 +982,7 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op)
quadriflow_free_job(job);
}
else {
- /* Non blocking call. For when the operator has been called from the gui */
+ /* Non blocking call. For when the operator has been called from the GUI. */
job->is_nonblocking_job = true;
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index b36d89dc37a..1e6a7b9f14e 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -317,7 +317,7 @@ bool ED_object_jump_to_object(bContext *C, Object *ob, const bool UNUSED(reveal_
/**
* Select and make the target object and bone active.
* Switches to Pose mode if in Object mode so the selection is visible.
- * Unhides the target bone and bone layer if necessary.
+ * Un-hides the target bone and bone layer if necessary.
*
* \returns false if object not in layer, bone not found, or other error
*/
@@ -1453,7 +1453,7 @@ void OBJECT_OT_select_less(wmOperatorType *ot)
static int object_select_random_exec(bContext *C, wmOperator *op)
{
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 1bb0246deb5..fd649854d8f 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -36,7 +36,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
@@ -44,7 +43,6 @@
#include "DNA_object_types.h"
#include "BKE_context.h"
-#include "BKE_curve.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 0528d64dca9..13c0740bce6 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -1394,7 +1394,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
* (all layers are considered without evaluating lock attributes) */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
/* undo matrix */
invert_m4_m4(inverse_diff_mat, diff_mat);
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
diff --git a/source/blender/editors/object/object_volume.c b/source/blender/editors/object/object_volume.c
index 6b46d43e5bf..fbdee00c29c 100644
--- a/source/blender/editors/object/object_volume.c
+++ b/source/blender/editors/object/object_volume.c
@@ -23,9 +23,6 @@
#include <string.h>
-#include "MEM_guardedalloc.h"
-
-#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_path_util.h"
diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c
index b36a8543d67..4b15385b537 100644
--- a/source/blender/editors/object/object_warp.c
+++ b/source/blender/editors/object/object_warp.c
@@ -36,7 +36,6 @@
#include "WM_types.h"
#include "ED_transverts.h"
-#include "ED_view3d.h"
#include "object_intern.h"
@@ -75,7 +74,7 @@ static void object_warp_transverts_minmax_x(TransVertStore *tvs,
for (int i = 0; i < tvs->transverts_tot; i++, tv++) {
float val;
- /* convert objectspace->viewspace */
+ /* Convert object-space to view-space. */
val = dot_m4_v3_row_x(mat_view, tv->loc);
min = min_ff(min, val);
@@ -123,7 +122,7 @@ static void object_warp_transverts(TransVertStore *tvs,
float co[3], co_add[2];
float val, phi;
- /* convert objectspace->viewspace */
+ /* Convert object-space to view-space. */
mul_v3_m4v3(co, mat_view, tv->loc);
sub_v2_v2(co, center_view);
@@ -158,7 +157,7 @@ static void object_warp_transverts(TransVertStore *tvs,
add_v2_v2(co, co_add);
- /* convert viewspace->objectspace */
+ /* Convert view-space to object-space. */
add_v2_v2(co, center_view);
mul_v3_m4v3(tv->loc, imat_view, co);
}
@@ -187,7 +186,7 @@ static int object_warp_verts_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* get viewmatrix */
+ /* Get view-matrix. */
{
PropertyRNA *prop_viewmat = RNA_struct_find_property(op->ptr, "viewmat");
if (RNA_property_is_set(op->ptr, prop_viewmat)) {
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 381bf317bee..a761701f60b 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -233,7 +233,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op)
/* if type is already enabled, toggle it off */
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
- int exists = dynamicPaint_outputLayerExists(surface, ob, output);
+ bool exists = dynamicPaint_outputLayerExists(surface, ob, output);
const char *name;
if (output == 0) {
diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c
index 22cfa50aee9..9b8622e6eac 100644
--- a/source/blender/editors/physics/particle_boids.c
+++ b/source/blender/editors/physics/particle_boids.c
@@ -33,7 +33,6 @@
#include "BKE_boids.h"
#include "BKE_context.h"
#include "BKE_main.h"
-#include "BKE_particle.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 8ab25fa74b8..d7e30f2b65c 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -1999,7 +1999,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
int p;
int k;
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
RNG *rng;
@@ -2905,7 +2905,7 @@ static void remove_tagged_keys(Depsgraph *depsgraph, Object *ob, ParticleSystem
}
}
-/************************ subdivide opertor *********************/
+/************************ subdivide operator *********************/
/* works like normal edit mode subdivide, inserts keys between neighboring selected keys */
static void subdivide_particle(PEData *data, int pa_index)
@@ -3029,7 +3029,7 @@ void PARTICLE_OT_subdivide(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/************************ remove doubles opertor *********************/
+/************************ remove doubles operator *********************/
static int remove_doubles_exec(bContext *C, wmOperator *op)
{
@@ -3750,8 +3750,7 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
}
}
else {
- /* compute position as if hair was standing up straight.
- * */
+ /* Compute position as if hair was standing up straight. */
float length;
copy_v3_v3(co_prev, co);
copy_v3_v3(co, key->co);
@@ -4566,7 +4565,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
mval[0] = mouse[0];
mval[1] = mouse[1];
- /* disable locking temporatily for disconnected hair */
+ /* Disable locking temporarily for disconnected hair. */
if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) {
pset->flag &= ~PE_LOCK_FIRST;
}
@@ -5004,7 +5003,7 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- /* disable locking temporatily for disconnected hair */
+ /* Disable locking temporarily for disconnected hair. */
if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) {
pset->flag &= ~PE_LOCK_FIRST;
}
diff --git a/source/blender/editors/physics/particle_edit_undo.c b/source/blender/editors/physics/particle_edit_undo.c
index 77b8d410d81..5d2e0e5b6ef 100644
--- a/source/blender/editors/physics/particle_edit_undo.c
+++ b/source/blender/editors/physics/particle_edit_undo.c
@@ -247,7 +247,7 @@ static bool particle_undosys_step_encode(struct bContext *C,
static void particle_undosys_step_decode(struct bContext *C,
struct Main *UNUSED(bmain),
UndoStep *us_p,
- int UNUSED(dir),
+ const eUndoStepDir UNUSED(dir),
bool UNUSED(is_final))
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 32d2e39d6f6..a94a2b9b764 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -33,21 +33,17 @@
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_path_util.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_customdata.h"
#include "BKE_fluid.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
#include "BKE_report.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
#include "DEG_depsgraph.h"
@@ -59,11 +55,9 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "manta_fluid_API.h"
#include "physics_intern.h" /* own include */
#include "DNA_fluid_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
#define FLUID_JOB_BAKE_ALL "FLUID_OT_bake_all"
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index eb154b97eb0..f5b80679689 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -23,14 +23,9 @@
#include <stdlib.h>
-#include "RNA_access.h"
-
#include "WM_api.h"
-#include "WM_types.h"
-#include "ED_object.h"
#include "ED_physics.h"
-#include "ED_select_utils.h"
#include "physics_intern.h" /* own include */
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index 1d5903bf417..ea8a4ce2a79 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -34,7 +34,6 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_layer.h"
-#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "DEG_depsgraph.h"
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index 4fd304ea71d..81a8b57776b 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -34,9 +34,7 @@
#include "BLT_translation.h"
-#include "BKE_collection.h"
#include "BKE_context.h"
-#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_rigidbody.h"
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 10cf4131584..50ba5907703 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -43,14 +43,10 @@
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
-#include "BKE_blender_undo.h"
-#include "BKE_blender_version.h"
-#include "BKE_camera.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
-#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -58,19 +54,15 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_undo_system.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_object.h"
#include "ED_render.h"
#include "ED_screen.h"
-#include "ED_undo.h"
#include "ED_util.h"
-#include "ED_view3d.h"
#include "BIF_glutil.h"
@@ -85,8 +77,6 @@
#include "SEQ_relations.h"
-#include "BLO_undofile.h"
-
#include "render_intern.h"
/* Render Callbacks */
@@ -1098,7 +1088,7 @@ void RENDER_OT_render(wmOperatorType *ot)
ot->cancel = screen_render_cancel;
ot->exec = screen_render_exec;
- /* this isn't needed, causes failer in background mode */
+ /* This isn't needed, causes failure in background mode. */
#if 0
ot->poll = ED_operator_screenactive;
#endif
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 4cb6994bc4b..71e4dca3ab1 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -363,7 +363,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
}
}
else {
- /* shouldnt suddenly give errors mid-render but possible */
+ /* shouldn't suddenly give errors mid-render but possible */
char err_out[256] = "unknown";
ImBuf *ibuf_view;
const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL;
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 6cf8515bdbb..4e766841c24 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -200,6 +200,11 @@ static bool check_engine_supports_preview(Scene *scene)
return (type->flag & RE_USE_PREVIEW) != 0;
}
+static bool preview_method_is_render(int pr_method)
+{
+ return ELEM(pr_method, PR_ICON_RENDER, PR_BUTS_RENDER, PR_NODE_RENDER);
+}
+
void ED_preview_free_dbase(void)
{
if (G_pr_main) {
@@ -1179,7 +1184,7 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
return;
}
- /* waste of cpu cyles... but the imbuf API has no other way to scale fast (ton) */
+ /* Waste of cpu cycles... but the imbuf API has no other way to scale fast (ton). */
ima = IMB_dupImBuf(ibuf);
if (!ima) {
@@ -1352,13 +1357,12 @@ static void common_preview_startjob(void *customdata,
*/
static void other_id_types_preview_render(IconPreview *ip,
IconPreviewSize *cur_size,
- const bool is_deferred,
+ const int pr_method,
short *stop,
short *do_update,
float *progress)
{
ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
- const bool is_render = !is_deferred;
/* These types don't use the ShaderPreview mess, they have their own types and functions. */
BLI_assert(!ip->id || !ELEM(GS(ip->id->name), ID_OB));
@@ -1368,7 +1372,7 @@ static void other_id_types_preview_render(IconPreview *ip,
sp->owner = ip->owner;
sp->sizex = cur_size->sizex;
sp->sizey = cur_size->sizey;
- sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
+ sp->pr_method = pr_method;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
sp->id_copy = ip->id_copy;
@@ -1376,7 +1380,7 @@ static void other_id_types_preview_render(IconPreview *ip,
sp->own_id_copy = false;
Material *ma = NULL;
- if (is_render) {
+ if (sp->pr_method == PR_ICON_RENDER) {
BLI_assert(ip->id);
/* grease pencil use its own preview file */
@@ -1424,6 +1428,8 @@ static void icon_preview_startjob_all_sizes(void *customdata,
for (cur_size = ip->sizes.first; cur_size; cur_size = cur_size->next) {
PreviewImage *prv = ip->owner;
+ /* Is this a render job or a deferred loading job? */
+ const int pr_method = (prv->tag & PRV_TAG_DEFFERED) ? PR_ICON_DEFERRED : PR_ICON_RENDER;
if (*stop) {
break;
@@ -1434,7 +1440,7 @@ static void icon_preview_startjob_all_sizes(void *customdata,
continue;
}
- if (!check_engine_supports_preview(ip->scene)) {
+ if (preview_method_is_render(pr_method) && !check_engine_supports_preview(ip->scene)) {
continue;
}
@@ -1450,8 +1456,7 @@ static void icon_preview_startjob_all_sizes(void *customdata,
object_preview_render(ip, cur_size);
}
else {
- other_id_types_preview_render(
- ip, cur_size, (prv->tag & PRV_TAG_DEFFERED), stop, do_update, progress);
+ other_id_types_preview_render(ip, cur_size, pr_method, stop, do_update, progress);
}
}
}
@@ -1634,7 +1639,7 @@ void ED_preview_shader_job(const bContext *C,
/* Use workspace render only for buttons Window,
* since the other previews are related to the datablock. */
- if (!check_engine_supports_preview(scene)) {
+ if (preview_method_is_render(method) && !check_engine_supports_preview(scene)) {
return;
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 499ffac6028..4ed1cbd60a5 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -25,7 +25,6 @@
#include "DNA_light_types.h"
#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -33,7 +32,6 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
-#include "DNA_workspace_types.h"
#include "DNA_world_types.h"
#include "DRW_engine.h"
@@ -44,13 +42,11 @@
#include "BKE_context.h"
#include "BKE_icons.h"
-#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_scene.h"
-#include "BKE_workspace.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -65,8 +61,6 @@
#include "WM_api.h"
-#include "render_intern.h" /* own include */
-
#include <stdio.h>
/***************************** Render Engines ********************************/
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 581169d823e..2c71345699f 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -141,13 +141,15 @@ void ED_region_pixelspace(ARegion *region)
}
/* only exported for WM */
-void ED_region_do_listen(
- wmWindow *win, ScrArea *area, ARegion *region, wmNotifier *note, const Scene *scene)
+void ED_region_do_listen(wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *notifier = params->notifier;
+
/* generic notes first */
- switch (note->category) {
+ switch (notifier->category) {
case NC_WM:
- if (note->data == ND_FILEREAD) {
+ if (notifier->data == ND_FILEREAD) {
ED_region_tag_redraw(region);
}
break;
@@ -157,16 +159,16 @@ void ED_region_do_listen(
}
if (region->type && region->type->listener) {
- region->type->listener(win, area, region, note, scene);
+ region->type->listener(params);
}
}
/* only exported for WM */
-void ED_area_do_listen(wmWindow *win, ScrArea *area, wmNotifier *note, Scene *scene)
+void ED_area_do_listen(wmSpaceTypeListenerParams *params)
{
/* no generic notes? */
- if (area->type && area->type->listener) {
- area->type->listener(win, area, note, scene);
+ if (params->area->type && params->area->type->listener) {
+ params->area->type->listener(params);
}
}
@@ -289,7 +291,15 @@ static void region_draw_azone_tab_arrow(ScrArea *area, ARegion *region, AZone *a
float alpha = WM_region_use_viewport(area, region) ? 0.6f : 0.4f;
const float color[4] = {0.05f, 0.05f, 0.05f, alpha};
UI_draw_roundbox_aa(
- true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, color);
+ &(const rctf){
+ .xmin = (float)az->x1,
+ .xmax = (float)az->x2,
+ .ymin = (float)az->y1,
+ .ymax = (float)az->y2,
+ },
+ true,
+ 4.0f,
+ color);
draw_azone_arrow((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, az->edge);
}
@@ -373,7 +383,16 @@ static void region_draw_status_text(ScrArea *area, ARegion *region)
float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
UI_GetThemeColor3fv(TH_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true, x1, y1, x2, y2, 4.0f, color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
+ true,
+ 4.0f,
+ color);
UI_FontThemeColor(fontid, TH_TEXT);
}
@@ -418,16 +437,13 @@ void ED_area_do_msg_notify_tag_refresh(
ED_area_tag_refresh(area);
}
-void ED_area_do_mgs_subscribe_for_tool_header(
- /* Follow ARegionType.message_subscribe */
- const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+/* Follow ARegionType.message_subscribe */
+void ED_area_do_mgs_subscribe_for_tool_header(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
BLI_assert(region->regiontype == RGN_TYPE_TOOL_HEADER);
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
@@ -438,16 +454,12 @@ void ED_area_do_mgs_subscribe_for_tool_header(
mbus, &workspace->id, workspace, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
}
-void ED_area_do_mgs_subscribe_for_tool_ui(
- /* Follow ARegionType.message_subscribe */
- const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_area_do_mgs_subscribe_for_tool_ui(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
BLI_assert(region->regiontype == RGN_TYPE_UI);
const char *panel_category_tool = "Tool";
const char *category = UI_panel_category_active_get(region, false);
@@ -634,7 +646,16 @@ void ED_region_do_draw(bContext *C, ARegion *region)
WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_region_tag_redraw, __func__);
}
- ED_region_message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ wmRegionMessageSubscribeParams message_subscribe_params = {
+ .context = C,
+ .message_bus = mbus,
+ .workspace = workspace,
+ .scene = scene,
+ .screen = screen,
+ .area = area,
+ .region = region,
+ };
+ ED_region_message_subscribe(&message_subscribe_params);
}
}
@@ -4027,14 +4048,12 @@ void ED_region_cache_draw_cached_segments(
/**
* Generate subscriptions for this region.
*/
-void ED_region_message_subscribe(bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_region_message_subscribe(wmRegionMessageSubscribeParams *params)
{
+ ARegion *region = params->region;
+ const bContext *C = params->context;
+ struct wmMsgBus *mbus = params->message_bus;
+
if (region->gizmo_map != NULL) {
WM_gizmomap_message_subscribe(C, region->gizmo_map, region, mbus);
}
@@ -4044,7 +4063,7 @@ void ED_region_message_subscribe(bContext *C,
}
if (region->type->message_subscribe != NULL) {
- region->type->message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ region->type->message_subscribe(params);
}
}
diff --git a/source/blender/editors/screen/area_utils.c b/source/blender/editors/screen/area_utils.c
index 075759f1120..30553bb7f07 100644
--- a/source/blender/editors/screen/area_utils.c
+++ b/source/blender/editors/screen/area_utils.c
@@ -22,6 +22,8 @@
#include "DNA_userdef_types.h"
+#include "BKE_screen.h"
+
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -32,7 +34,6 @@
#include "ED_screen.h"
-#include "UI_interface.h"
#include "UI_interface_icons.h"
/* -------------------------------------------------------------------- */
@@ -42,14 +43,11 @@
/**
* Callback for #ARegionType.message_subscribe
*/
-void ED_region_generic_tools_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_region_generic_tools_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 33b918e6d4d..a88afecd064 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -57,11 +57,12 @@ static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state)
vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
-/* To be used before calling immDrawPixelsTex
- * Default shader is GPU_SHADER_2D_IMAGE_COLOR
- * You can still set uniforms with :
- * GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);
- * */
+/**
+ * To be used before calling #immDrawPixelsTex
+ * Default shader is #GPU_SHADER_2D_IMAGE_COLOR
+ * You can still set uniforms with:
+ * `GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);`
+ */
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
{
IMMDrawPixelsTexState state;
@@ -77,10 +78,11 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
return state;
}
-/* Use the currently bound shader.
+/**
+ * Use the currently bound shader.
*
- * Use immDrawPixelsTexSetup to bind the shader you
- * want before calling immDrawPixelsTex.
+ * Use #immDrawPixelsTexSetup to bind the shader you
+ * want before calling #immDrawPixelsTex.
*
* If using a special shader double check it uses the same
* attributes "pos" "texCoord" and uniform "image".
@@ -89,7 +91,7 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
*
* Be also aware that this function unbinds the shader when
* it's finished.
- * */
+ */
void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float x,
float y,
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 1dfe606be78..627a67358f2 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -866,7 +866,7 @@ static eContextResult screen_ctx_editable_gpencil_strokes(const bContext *C,
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
if (ED_gpencil_stroke_can_use_direct(area, gps)) {
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 6432bdac1b1..1ea64c542f5 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -478,7 +478,7 @@ void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac)
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* splitpoint */
+ /* Split-point. */
GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ub(255, 255, 255, 100);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index be52874ed0b..c25b572d200 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -871,6 +871,11 @@ static void screen_global_area_refresh(wmWindow *win,
const short height_min,
const short height_max)
{
+ /* Full-screens shouldn't have global areas. Don't touch them. */
+ if (screen->state == SCREENFULL) {
+ return;
+ }
+
ScrArea *area = NULL;
LISTBASE_FOREACH (ScrArea *, area_iter, &win->global_areas.areabase) {
if (area_iter->spacetype == space_type) {
@@ -1019,7 +1024,7 @@ void screen_change_update(bContext *C, wmWindow *win, bScreen *screen)
WM_event_add_notifier(C, NC_WINDOW, NULL);
WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTSET, layout);
- /* makes button hilites work */
+ /* Makes button highlights work. */
WM_event_add_mousemove(win);
}
@@ -1216,7 +1221,7 @@ void ED_screen_full_restore(bContext *C, ScrArea *area)
}
/**
- * \param toggle_area: If this is set, its space data will be swapped with the one of the new emtpy
+ * \param toggle_area: If this is set, its space data will be swapped with the one of the new empty
* area, when toggling back it can be swapped back again.
* \return The newly created screen with the non-normal area.
*/
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index a03e65d8a9d..c51ff559786 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -29,10 +29,10 @@ struct bContextDataResult;
/* internal exports only */
-#define AZONESPOTW UI_HEADER_OFFSET /* width of corner azone - max */
-#define AZONESPOTH (0.6f * U.widget_unit) /* height of corner azone */
-#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */
-#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */
+#define AZONESPOTW UI_HEADER_OFFSET /* width of corner #AZone - max */
+#define AZONESPOTH (0.6f * U.widget_unit) /* height of corner #AZone */
+#define AZONEFADEIN (5.0f * U.widget_unit) /* when #AZone is totally visible */
+#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the #AZone */
#define AREAJOINTOLERANCE (1.0f * U.widget_unit) /* Edges must be close to allow joining. */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index ca1c75be0a1..244d8c10e4e 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -1637,7 +1637,7 @@ static int area_snap_calc_location(const bScreen *screen,
/* Thirds. */
1.0f / 3.0f,
2.0f / 3.0f,
- /* Quaters. */
+ /* Quarters. */
1.0f / 4.0f,
3.0f / 4.0f,
/* Eighth. */
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 550913fc8af..7eb08cbabac 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -1755,7 +1755,7 @@ static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorCont
else if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_RADIAL &&
brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
/* Display the simulation limits if sculpting outside them. */
- /* This does not makes much sense of plane falloff as the falloff is infinte or global. */
+ /* This does not makes much sense of plane falloff as the falloff is infinite or global. */
if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) >
ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
diff --git a/source/blender/editors/sculpt_paint/paint_curve_undo.c b/source/blender/editors/sculpt_paint/paint_curve_undo.c
index a8e22f66734..dbe522bf304 100644
--- a/source/blender/editors/sculpt_paint/paint_curve_undo.c
+++ b/source/blender/editors/sculpt_paint/paint_curve_undo.c
@@ -126,7 +126,7 @@ static bool paintcurve_undosys_step_encode(struct bContext *C,
static void paintcurve_undosys_step_decode(struct bContext *UNUSED(C),
struct Main *UNUSED(bmain),
UndoStep *us_p,
- int UNUSED(dir),
+ const eUndoStepDir UNUSED(dir),
bool UNUSED(is_final))
{
PaintCurveUndoStep *us = (PaintCurveUndoStep *)us_p;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 5c15fd05116..f7c0f7718bb 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -138,7 +138,7 @@ BLI_INLINE uchar f_to_char(const float val)
#ifndef PROJ_DEBUG_NOSEAMBLEED
/* projectFaceSeamFlags options */
-//#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, backfacing or occluded */
+//#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, back-facing or occluded. */
//#define PROJ_FACE_INIT (1<<1) /* When we have initialized the faces data */
/* If this face has a seam on any of its edges. */
@@ -150,7 +150,7 @@ BLI_INLINE uchar f_to_char(const float val)
# define PROJ_FACE_NOSEAM1 (1 << 5)
# define PROJ_FACE_NOSEAM2 (1 << 6)
-/* If the seam is completely initialized, including adjecent seams. */
+/* If the seam is completely initialized, including adjacent seams. */
# define PROJ_FACE_SEAM_INIT0 (1 << 8)
# define PROJ_FACE_SEAM_INIT1 (1 << 9)
# define PROJ_FACE_SEAM_INIT2 (1 << 10)
@@ -294,7 +294,7 @@ typedef struct ProjPaintState {
/** verts projected into floating point screen space. */
float (*screenCoords)[4];
- /** 2D bounds for mesh verts on the screen's plane (screenspace). */
+ /** 2D bounds for mesh verts on the screen's plane (screen-space). */
float screenMin[2];
float screenMax[2];
/** Calculated from screenMin & screenMax. */
@@ -310,10 +310,10 @@ typedef struct ProjPaintState {
bool do_stencil_brush;
bool do_material_slots;
- /** Use raytraced occlusion? - ortherwise will paint right through to the back. */
+ /** Use ray-traced occlusion? - otherwise will paint right through to the back. */
bool do_occlude;
/** ignore faces with normals pointing away,
- * skips a lot of raycasts if your normals are correctly flipped. */
+ * skips a lot of ray-casts if your normals are correctly flipped. */
bool do_backfacecull;
/** mask out pixels based on their normals. */
bool do_mask_normal;
@@ -579,7 +579,7 @@ static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_i
/* fast projection bucket array lookup, use the safe version for bound checking */
static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
{
- /* If we were not dealing with screenspace 2D coords we could simple do...
+ /* If we were not dealing with screen-space 2D coords we could simple do...
* ps->bucketRect[x + (y*ps->buckets_y)] */
/* please explain?
@@ -887,8 +887,8 @@ static int project_paint_occlude_ptv_clip(const float pt[3],
return -1;
}
-/* Check if a screenspace location is occluded by any other faces
- * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
+/* Check if a screen-space location is occluded by any other faces
+ * check, pixelScreenCo must be in screen-space, its Z-Depth only needs to be used for comparison
* and doesn't need to be correct in relation to X and Y coords
* (this is the case in perspective view) */
static bool project_bucket_point_occluded(const ProjPaintState *ps,
@@ -1514,10 +1514,10 @@ static void project_face_seams_init(const ProjPaintState *ps,
}
#endif // PROJ_DEBUG_NOSEAMBLEED
-/* Converts a UV location to a 3D screenspace location
+/* Converts a UV location to a 3D screen-space location
* Takes a 'uv' and 3 UV coords, and sets the values of pixelScreenCo
*
- * This is used for finding a pixels location in screenspace for painting */
+ * This is used for finding a pixels location in screen-space for painting */
static void screen_px_from_ortho(const float uv[2],
const float v1co[3],
const float v2co[3],
@@ -1537,7 +1537,7 @@ static void screen_px_from_ortho(const float uv[2],
static void screen_px_from_persp(const float uv[2],
const float v1co[4],
const float v2co[4],
- const float v3co[4], /* screenspace coords */
+ const float v3co[4], /* screen-space coords */
const float uv1co[2],
const float uv2co[2],
const float uv3co[2],
@@ -1923,7 +1923,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
projPixel->newColor.uint = 0;
}
- /* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
+ /* Screen-space unclamped, we could keep its z and w values but don't need them at the moment. */
if (ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
copy_v3_v3(projPixel->worldCoSS, world_spaceCo);
}
@@ -2304,14 +2304,14 @@ static bool project_bucket_isect_circle(const float cent[2],
return false;
}
-/* Note for rect_to_uvspace_ortho() and rect_to_uvspace_persp()
+/* Note for #rect_to_uvspace_ortho() and #rect_to_uvspace_persp()
* in ortho view this function gives good results when bucket_bounds are outside the triangle
* however in some cases, perspective view will mess up with faces
- * that have minimal screenspace area (viewed from the side).
+ * that have minimal screen-space area (viewed from the side).
*
* for this reason its not reliable in this case so we'll use the Simple Barycentric'
- * funcs that only account for points inside the triangle.
- * however switching back to this for ortho is always an option */
+ * functions that only account for points inside the triangle.
+ * however switching back to this for ortho is always an option. */
static void rect_to_uvspace_ortho(const rctf *bucket_bounds,
const float *v1coSS,
@@ -2415,9 +2415,10 @@ static bool IsectPT2Df_limit(
(area_tri_v2(v1, v2, v3))) < limit;
}
-/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
+/**
+ * Clip the face by a bucket and set the uv-space bucket_bounds_uv
* so we have the clipped UV's to do pixel intersection tests with
- * */
+ */
static int float_z_sort_flip(const void *p1, const void *p2)
{
return (((float *)p1)[2] < ((float *)p2)[2] ? 1 : -1);
@@ -2516,8 +2517,8 @@ static void project_bucket_clip_face(const bool is_ortho,
flip = (((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != is_flip_object) !=
(line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
- /* all screenspace points are inside the bucket bounding box,
- * this means we don't need to clip and can simply return the UVs */
+ /* All screen-space points are inside the bucket bounding box,
+ * this means we don't need to clip and can simply return the UVs. */
if (flip) { /* facing the back? */
copy_v2_v2(bucket_bounds_uv[0], uv3co);
copy_v2_v2(bucket_bounds_uv[1], uv2co);
@@ -2634,7 +2635,7 @@ static void project_bucket_clip_face(const bool is_ortho,
(line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
if (inside_face_flag == ISECT_ALL4) {
- /* bucket is totally inside the screenspace face, we can safely use weights */
+ /* Bucket is totally inside the screen-space face, we can safely use weights. */
if (is_ortho) {
rect_to_uvspace_ortho(
@@ -2655,7 +2656,7 @@ static void project_bucket_clip_face(const bool is_ortho,
* The 2 cases above are where the face is inside the bucket
* or the bucket is inside the face.
*
- * we need to make a convex polyline from the intersection between the screenspace face
+ * we need to make a convex poly-line from the intersection between the screen-space face
* and the bucket bounds.
*
* There are a number of ways this could be done, currently it just collects all
@@ -2996,7 +2997,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
/* vert co screen-space, these will be assigned to lt_vtri[0-2] */
const float *v1coSS, *v2coSS, *v3coSS;
- /* vertex screenspace coords */
+ /* Vertex screen-space coords. */
const float *vCo[3];
float w[3], wco[3];
@@ -3006,9 +3007,9 @@ static void project_paint_face_init(const ProjPaintState *ps,
float pixelScreenCo[4];
bool do_3d_mapping = ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D;
- /* ispace bounds */
+ /* Image-space bounds. */
rcti bounds_px;
- /* vars for getting uvspace bounds */
+ /* Variables for getting UV-space bounds. */
/* bucket bounds in UV space so we can init pixels only for this face, */
float lt_uv_pxoffset[3][2];
@@ -3206,10 +3207,10 @@ static void project_paint_face_init(const ProjPaintState *ps,
/* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in perspective view */
float insetCos[3][3];
- /* vertex screenspace coords */
+ /* Vertex screen-space coords. */
const float *vCoSS[3];
- /* Store the screenspace coords of the face,
+ /* Store the screen-space coords of the face,
* clipped by the bucket's screen aligned rectangle. */
float bucket_clip_edges[2][2];
float edge_verts_inset_clip[2][3];
@@ -3418,7 +3419,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
}
/**
- * Takes floating point screenspace min/max and
+ * Takes floating point screen-space min/max and
* returns int min/max to be used as indices for ps->bucketRect, ps->bucketFlags
*/
static void project_paint_bucket_bounds(const ProjPaintState *ps,
@@ -3887,7 +3888,7 @@ static void proj_paint_state_cavity_init(ProjPaintState *ps)
float no[3];
mul_v3_fl(edges[a], 1.0f / counter[a]);
normal_short_to_float_v3(no, mv->no);
- /* augment the diffe*/
+ /* Augment the difference. */
cavities[a] = saacos(10.0f * dot_v3v3(no, edges[a])) * (float)M_1_PI;
}
else {
@@ -4307,7 +4308,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
slot_last = slot;
}
- /* don't allow using the same inage for painting and stencilling */
+ /* Don't allow using the same image for painting and stenciling. */
if (slot->ima == ps->stencil_ima) {
/* Delay continuing the loop until after loop_uvs and bleed faces are initialized.
* While this shouldn't be used, face-winding reads all polys.
@@ -4337,7 +4338,6 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
continue;
}
- /* tfbase here should be non-null! */
BLI_assert(mloopuv_base != NULL);
if (is_face_sel && tpage) {
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 8eb2ebd0f19..8fd5759d695 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -168,8 +168,11 @@ void PAINT_OT_weight_from_bones(wmOperatorType *ot)
/** \name Sample Weight Operator
* \{ */
-/* sets wp->weight to the closest weight value to vertex */
-/* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
+/**
+ * Sets wp->weight to the closest weight value to vertex.
+ *
+ * \note we can't sample front-buffer, weight colors are interpolated too unpredictable.
+ */
static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -201,7 +204,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
}
else if (ED_mesh_pick_face(
C, vc.obact, event->mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
- /* this relies on knowning the internal worksings of ED_mesh_pick_face_vert() */
+ /* This relies on knowing the internal workings of #ED_mesh_pick_face_vert() */
BKE_report(
op->reports, RPT_WARNING, "The modifier used does not support deformed locations");
}
@@ -604,7 +607,7 @@ static void gradientVert_update(WPGradient_userData *grad_data, int index)
Mesh *me = grad_data->me;
WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index];
- /* Optionally restrict to assigned verices only. */
+ /* Optionally restrict to assigned vertices only. */
if (grad_data->use_vgroup_restrict && ((vs->flag & VGRAD_STORE_DW_EXIST) == 0)) {
return;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index cb5d708908b..d1028e5f542 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -391,13 +391,14 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl
case PBVH_FACES:
case PBVH_GRIDS:
for (int i = 0; i < ss->totfaces; i++) {
- if (abs(ss->face_sets[i]) == face_set) {
- if (visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
+ if (abs(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]);
}
}
break;
@@ -1057,12 +1058,13 @@ bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3],
char symm)
{
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- float location[3];
- flip_v3_v3(location, br_co, (char)i);
- if (len_squared_v3v3(location, vertex) < radius * radius) {
- return true;
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ float location[3];
+ flip_v3_v3(location, br_co, (char)i);
+ if (len_squared_v3v3(location, vertex) < radius * radius) {
+ return true;
}
}
return false;
@@ -1107,20 +1109,22 @@ void SCULPT_floodfill_add_initial_with_symmetry(
/* Add active vertex and symmetric vertices to the queue. */
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- int v = -1;
- if (i == 0) {
- v = index;
- }
- else if (radius > 0.0f) {
- float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
- float location[3];
- flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i);
- v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
- }
- if (v != -1) {
- SCULPT_floodfill_add_initial(flood, v);
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ int v = -1;
+ if (i == 0) {
+ v = index;
+ }
+ else if (radius > 0.0f) {
+ float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
+ float location[3];
+ flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i);
+ v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
+ }
+
+ if (v != -1) {
+ SCULPT_floodfill_add_initial(flood, v);
}
}
}
@@ -1131,20 +1135,22 @@ void SCULPT_floodfill_add_active(
/* Add active vertex and symmetric vertices to the queue. */
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- int v = -1;
- if (i == 0) {
- v = SCULPT_active_vertex_get(ss);
- }
- else if (radius > 0.0f) {
- float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
- float location[3];
- flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), i);
- v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
- }
- if (v != -1) {
- SCULPT_floodfill_add_initial(flood, v);
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ int v = -1;
+ if (i == 0) {
+ v = SCULPT_active_vertex_get(ss);
+ }
+ else if (radius > 0.0f) {
+ float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
+ float location[3];
+ flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), i);
+ v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
+ }
+
+ if (v != -1) {
+ SCULPT_floodfill_add_initial(flood, v);
}
}
}
@@ -1161,12 +1167,19 @@ void SCULPT_floodfill_execute(
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const int to_v = ni.index;
- if (!BLI_BITMAP_TEST(flood->visited_vertices, to_v) && SCULPT_vertex_visible_get(ss, to_v)) {
- BLI_BITMAP_ENABLE(flood->visited_vertices, to_v);
- if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
- BLI_gsqueue_push(flood->queue, &to_v);
- }
+ if (BLI_BITMAP_TEST(flood->visited_vertices, to_v)) {
+ continue;
+ }
+
+ if (!SCULPT_vertex_visible_get(ss, to_v)) {
+ continue;
+ }
+
+ BLI_BITMAP_ENABLE(flood->visited_vertices, to_v);
+
+ if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
+ BLI_gsqueue_push(flood->queue, &to_v);
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -1466,40 +1479,42 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
unode = SCULPT_undo_get_node(data->nodes[n]);
}
- if (unode) {
- PBVHVertexIter vd;
- SculptOrigVertData orig_data;
+ if (!unode) {
+ return;
+ }
- SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
+ PBVHVertexIter vd;
+ SculptOrigVertData orig_data;
- BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
- {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
- if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
- copy_v3_v3(vd.co, orig_data.co);
- if (vd.no) {
- copy_v3_v3_short(vd.no, orig_data.no);
- }
- else {
- normal_short_to_float_v3(vd.fno, orig_data.no);
- }
- }
- else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
- *vd.mask = orig_data.mask;
- }
- else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
- copy_v4_v4(vd.col, orig_data.col);
- }
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
+ copy_v3_v3(vd.co, orig_data.co);
+ if (vd.no) {
+ copy_v3_v3_short(vd.no, orig_data.no);
+ }
+ else {
+ normal_short_to_float_v3(vd.fno, orig_data.no);
}
}
- BKE_pbvh_vertex_iter_end;
+ else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
+ *vd.mask = orig_data.mask;
+ }
+ else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
+ copy_v4_v4(vd.col, orig_data.col);
+ }
- BKE_pbvh_node_mark_update(data->nodes[n]);
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
}
+ BKE_pbvh_vertex_iter_end;
+
+ BKE_pbvh_node_mark_update(data->nodes[n]);
}
static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
@@ -1545,11 +1560,15 @@ static void sculpt_extend_redraw_rect_previous(Object *ob, rcti *rect)
* mesh parts could disappear from screen (sergey). */
SculptSession *ss = ob->sculpt;
- if (ss->cache) {
- if (!BLI_rcti_is_empty(&ss->cache->previous_r)) {
- BLI_rcti_union(rect, &ss->cache->previous_r);
- }
+ if (!ss->cache) {
+ return;
+ }
+
+ if (BLI_rcti_is_empty(&ss->cache->previous_r)) {
+ return;
}
+
+ BLI_rcti_union(rect, &ss->cache->previous_r);
}
/* Get a screen-space rectangle of the modified area. */
@@ -1651,28 +1670,30 @@ bool SCULPT_brush_test_sphere(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = sqrtf(distsq);
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+
+ test->dist = sqrtf(distsq);
+ return true;
}
bool SCULPT_brush_test_sphere_sq(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = distsq;
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+ test->dist = distsq;
+ return true;
}
bool SCULPT_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3])
@@ -1689,14 +1710,16 @@ bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3])
closest_to_plane_normalized_v3(co_proj, test->plane_view, co);
float distsq = len_squared_v3v3(co_proj, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = distsq;
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+
+ test->dist = distsq;
+ return true;
}
bool SCULPT_brush_test_cube(SculptBrushTest *test,
@@ -1724,25 +1747,26 @@ bool SCULPT_brush_test_cube(SculptBrushTest *test,
const float constant_side = hardness * side;
const float falloff_side = roundness * side;
- if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) {
+ if (!(local_co[0] <= side && local_co[1] <= side && local_co[2] <= side)) {
+ /* Outside the square. */
+ return false;
+ }
+ if (min_ff(local_co[0], local_co[1]) > constant_side) {
/* Corner, distance to the center of the corner circle. */
- if (min_ff(local_co[0], local_co[1]) > constant_side) {
- float r_point[3];
- copy_v3_fl(r_point, constant_side);
- test->dist = len_v2v2(r_point, local_co) / falloff_side;
- return true;
- }
+ float r_point[3];
+ copy_v3_fl(r_point, constant_side);
+ test->dist = len_v2v2(r_point, local_co) / falloff_side;
+ return true;
+ }
+ if (max_ff(local_co[0], local_co[1]) > constant_side) {
/* Side, distance to the square XY axis. */
- if (max_ff(local_co[0], local_co[1]) > constant_side) {
- test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
- return true;
- }
- /* Inside the square, constant distance. */
- test->dist = 0.0f;
+ test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
return true;
}
- /* Outside the square. */
- return false;
+
+ /* Inside the square, constant distance. */
+ test->dist = 0.0f;
+ return true;
}
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
@@ -1777,21 +1801,21 @@ static float frontface(const Brush *br,
const short no[3],
const float fno[3])
{
- if (br->flag & BRUSH_FRONTFACE) {
- float dot;
+ if (!(br->flag & BRUSH_FRONTFACE)) {
+ return 1.0f;
+ }
- if (no) {
- float tmp[3];
+ float dot;
+ if (no) {
+ float tmp[3];
- normal_short_to_float_v3(tmp, no);
- dot = dot_v3v3(tmp, sculpt_normal);
- }
- else {
- dot = dot_v3v3(fno, sculpt_normal);
- }
- return dot > 0.0f ? dot : 0.0f;
+ normal_short_to_float_v3(tmp, no);
+ dot = dot_v3v3(tmp, sculpt_normal);
+ }
+ else {
+ dot = dot_v3v3(fno, sculpt_normal);
}
- return 1.0f;
+ return dot > 0.0f ? dot : 0.0f;
}
#if 0
@@ -1871,25 +1895,25 @@ static float calc_radial_symmetry_feather(Sculpt *sd,
static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache)
{
- if (sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER) {
- float overlap;
- const int symm = cache->symmetry;
-
- overlap = 0.0f;
- for (int i = 0; i <= symm; i++) {
- if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
-
- overlap += calc_overlap(cache, i, 0, 0);
+ if (!(sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER)) {
+ return 1.0f;
+ }
+ float overlap;
+ const int symm = cache->symmetry;
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'X');
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y');
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z');
- }
+ overlap = 0.0f;
+ for (int i = 0; i <= symm; i++) {
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
}
- return 1.0f / overlap;
+ overlap += calc_overlap(cache, i, 0, 0);
+
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'X');
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y');
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z');
}
- return 1.0f;
+ return 1.0f / overlap;
}
/* -------------------------------------------------------------------- */
@@ -1991,35 +2015,37 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
- if (normal_test_r || area_test_r) {
- float no[3];
- int flip_index;
+ if (!normal_test_r && !area_test_r) {
+ continue;
+ }
- normal_tri_v3(no, UNPACK3(co_tri));
+ float no[3];
+ int flip_index;
- flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
- if (use_area_cos && area_test_r) {
- /* Weight the coordinates towards the center. */
- float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
- const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ normal_tri_v3(no, UNPACK3(co_tri));
- float disp[3];
- sub_v3_v3v3(disp, co, area_test.location);
- mul_v3_fl(disp, 1.0f - afactor);
- add_v3_v3v3(co, area_test.location, disp);
- add_v3_v3(anctd->area_cos[flip_index], co);
+ flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
+ if (use_area_cos && area_test_r) {
+ /* Weight the coordinates towards the center. */
+ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
+ const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- anctd->count_co[flip_index] += 1;
- }
- if (use_area_nos && normal_test_r) {
- /* Weight the normals towards the center. */
- float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
- const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- mul_v3_fl(no, nfactor);
-
- add_v3_v3(anctd->area_nos[flip_index], no);
- anctd->count_no[flip_index] += 1;
- }
+ float disp[3];
+ sub_v3_v3v3(disp, co, area_test.location);
+ mul_v3_fl(disp, 1.0f - afactor);
+ add_v3_v3v3(co, area_test.location, disp);
+ add_v3_v3(anctd->area_cos[flip_index], co);
+
+ anctd->count_co[flip_index] += 1;
+ }
+ if (use_area_nos && normal_test_r) {
+ /* Weight the normals towards the center. */
+ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
+ const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ mul_v3_fl(no, nfactor);
+
+ add_v3_v3(anctd->area_nos[flip_index], no);
+ anctd->count_no[flip_index] += 1;
}
}
}
@@ -2051,49 +2077,51 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
- if (normal_test_r || area_test_r) {
- float no[3];
- int flip_index;
+ if (!normal_test_r && !area_test_r) {
+ continue;
+ }
+
+ float no[3];
+ int flip_index;
- data->any_vertex_sampled = true;
+ data->any_vertex_sampled = true;
- if (use_original) {
- normal_short_to_float_v3(no, no_s);
+ if (use_original) {
+ normal_short_to_float_v3(no, no_s);
+ }
+ else {
+ if (vd.no) {
+ normal_short_to_float_v3(no, vd.no);
}
else {
- if (vd.no) {
- normal_short_to_float_v3(no, vd.no);
- }
- else {
- copy_v3_v3(no, vd.fno);
- }
+ copy_v3_v3(no, vd.fno);
}
+ }
- flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
- 0.0f);
+ flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
+ 0.0f);
- if (use_area_cos && area_test_r) {
- /* Weight the coordinates towards the center. */
- float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
- const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ if (use_area_cos && area_test_r) {
+ /* Weight the coordinates towards the center. */
+ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
+ const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- float disp[3];
- sub_v3_v3v3(disp, co, area_test.location);
- mul_v3_fl(disp, 1.0f - afactor);
- add_v3_v3v3(co, area_test.location, disp);
+ float disp[3];
+ sub_v3_v3v3(disp, co, area_test.location);
+ mul_v3_fl(disp, 1.0f - afactor);
+ add_v3_v3v3(co, area_test.location, disp);
- add_v3_v3(anctd->area_cos[flip_index], co);
- anctd->count_co[flip_index] += 1;
- }
- if (use_area_nos && normal_test_r) {
- /* Weight the normals towards the center. */
- float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
- const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- mul_v3_fl(no, nfactor);
-
- add_v3_v3(anctd->area_nos[flip_index], no);
- anctd->count_no[flip_index] += 1;
- }
+ add_v3_v3(anctd->area_cos[flip_index], co);
+ anctd->count_co[flip_index] += 1;
+ }
+ if (use_area_nos && normal_test_r) {
+ /* Weight the normals towards the center. */
+ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
+ const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ mul_v3_fl(no, nfactor);
+
+ add_v3_v3(anctd->area_nos[flip_index], no);
+ anctd->count_no[flip_index] += 1;
}
}
BKE_pbvh_vertex_iter_end;
@@ -2150,10 +2178,12 @@ static void calc_area_center(
/* For flatten center. */
for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
- if (anctd.count_co[n] != 0) {
- mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
- break;
+ if (anctd.count_co[n] == 0) {
+ continue;
}
+
+ mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
+ break;
}
if (n == 2) {
@@ -2249,10 +2279,12 @@ static void calc_area_normal_and_center(
/* For flatten center. */
for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
- if (anctd.count_co[n] != 0) {
- mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
- break;
+ if (anctd.count_co[n] == 0) {
+ continue;
}
+
+ mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
+ break;
}
if (n == 2) {
@@ -2892,26 +2924,27 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
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)) {
- const float fade =
- bstrength *
- SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.index, thread_id) *
- ss->cache->pressure;
+ 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.index, thread_id) *
+ ss->cache->pressure;
- float avg[3], val[3];
+ float avg[3], val[3];
- SCULPT_bmesh_four_neighbor_average(avg, direction, vd.bm_vert);
+ SCULPT_bmesh_four_neighbor_average(avg, direction, vd.bm_vert);
- sub_v3_v3v3(val, avg, vd.co);
+ sub_v3_v3v3(val, avg, vd.co);
- madd_v3_v3v3fl(val, vd.co, val, fade);
+ madd_v3_v3v3fl(val, vd.co, val, fade);
- SCULPT_clip(sd, ss, vd.co, val);
+ SCULPT_clip(sd, ss, vd.co, val);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -2964,21 +2997,23 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- if (bstrength > 0.0f) {
- (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
- }
- else {
- (*vd.mask) += fade * bstrength * (*vd.mask);
- }
- *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f);
+ const float fade = SCULPT_brush_strength_factor(
+ ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (bstrength > 0.0f) {
+ (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
+ }
+ else {
+ (*vd.mask) += fade * bstrength * (*vd.mask);
+ }
+ *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
BKE_pbvh_vertex_iter_end;
}
@@ -3039,26 +3074,27 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
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)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
- float limit_co[3];
- float disp[3];
- SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co);
- sub_v3_v3v3(disp, limit_co, vd.co);
- mul_v3_v3fl(proxy[vd.i], disp, fade);
+ float limit_co[3];
+ float disp[3];
+ SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co);
+ sub_v3_v3v3(disp, limit_co, vd.co);
+ mul_v3_v3fl(proxy[vd.i], disp, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3151,12 +3187,15 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata,
ss->cache->limit_surface_co[vd.index]);
const float *neighbor_limit_surface_disp = ss->cache->prev_displacement[ni.index];
normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) {
- const float disp_interp = clamp_f(
- -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
- madd_v3_v3fl(interp_limit_surface_disp, neighbor_limit_surface_disp, disp_interp);
- weights_accum += disp_interp;
+
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
+ continue;
}
+
+ const float disp_interp = clamp_f(
+ -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
+ madd_v3_v3fl(interp_limit_surface_disp, neighbor_limit_surface_disp, disp_interp);
+ weights_accum += disp_interp;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -3246,23 +3285,24 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- /* Offset vertex. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3325,23 +3365,24 @@ static void do_draw_sharp_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);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- /* Offset vertex. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3407,52 +3448,53 @@ static void do_topology_slide_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);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float current_disp[3];
- float current_disp_norm[3];
- float final_disp[3] = {0.0f, 0.0f, 0.0f};
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float current_disp[3];
+ float current_disp_norm[3];
+ float final_disp[3] = {0.0f, 0.0f, 0.0f};
- switch (brush->slide_deform_type) {
- case BRUSH_SLIDE_DEFORM_DRAG:
- sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
- break;
- case BRUSH_SLIDE_DEFORM_PINCH:
- sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
- break;
- case BRUSH_SLIDE_DEFORM_EXPAND:
- sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
- break;
- }
+ switch (brush->slide_deform_type) {
+ case BRUSH_SLIDE_DEFORM_DRAG:
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ break;
+ case BRUSH_SLIDE_DEFORM_PINCH:
+ sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
+ break;
+ case BRUSH_SLIDE_DEFORM_EXPAND:
+ sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
+ break;
+ }
- normalize_v3_v3(current_disp_norm, current_disp);
- mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
-
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
- float vertex_disp[3];
- float vertex_disp_norm[3];
- sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
- normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) {
- madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
- }
+ normalize_v3_v3(current_disp_norm, current_disp);
+ mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ float vertex_disp[3];
+ float vertex_disp_norm[3];
+ sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
+ normalize_v3_v3(vertex_disp_norm, vertex_disp);
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) {
+ madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- mul_v3_v3fl(proxy[vd.i], final_disp, fade);
+ mul_v3_v3fl(proxy[vd.i], final_disp, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3482,16 +3524,17 @@ void SCULPT_relax_vertex(SculptSession *ss,
/* When the vertex to relax is boundary, use only connected boundary vertices for the average
* position. */
if (is_boundary) {
- if (SCULPT_vertex_is_boundary(ss, ni.index)) {
- add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
- avg_count++;
-
- /* Calculate a normal for the constraint plane using the edges of the boundary. */
- float to_neighbor[3];
- sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
- normalize_v3(to_neighbor);
- add_v3_v3(boundary_normal, to_neighbor);
+ if (!SCULPT_vertex_is_boundary(ss, ni.index)) {
+ continue;
}
+ add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
+ avg_count++;
+
+ /* Calculate a normal for the constraint plane using the edges of the boundary. */
+ float to_neighbor[3];
+ sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
+ normalize_v3(to_neighbor);
+ add_v3_v3(boundary_normal, to_neighbor);
}
else {
add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
@@ -3563,21 +3606,22 @@ static void do_topology_relax_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);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3728,38 +3772,39 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- /* Offset vertex. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float val1[3];
- float val2[3];
-
- /* First we pinch. */
- sub_v3_v3v3(val1, test.location, vd.co);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(val1, val1, ss->cache->view_normal);
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float val1[3];
+ float val2[3];
+
+ /* First we pinch. */
+ sub_v3_v3v3(val1, test.location, vd.co);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(val1, val1, ss->cache->view_normal);
+ }
- mul_v3_fl(val1, fade * flippedbstrength);
+ mul_v3_fl(val1, fade * flippedbstrength);
- sculpt_project_v3(spvc, val1, val1);
+ sculpt_project_v3(spvc, val1, val1);
- /* Then we draw. */
- mul_v3_v3fl(val2, offset, fade);
+ /* Then we draw. */
+ mul_v3_v3fl(val2, offset, fade);
- add_v3_v3v3(proxy[vd.i], val1, val2);
+ add_v3_v3v3(proxy[vd.i], val1, val2);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3845,40 +3890,41 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float disp_center[3];
- float x_disp[3];
- float z_disp[3];
- /* Calculate displacement from the vertex to the brush center. */
- sub_v3_v3v3(disp_center, test.location, vd.co);
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float disp_center[3];
+ float x_disp[3];
+ float z_disp[3];
+ /* Calculate displacement from the vertex to the brush center. */
+ sub_v3_v3v3(disp_center, test.location, vd.co);
- /* Project the displacement into the X vector (aligned to the stroke). */
- mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
+ /* Project the displacement into the X vector (aligned to the stroke). */
+ mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
- /* Project the displacement into the Z vector (aligned to the surface normal). */
- mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
+ /* Project the displacement into the Z vector (aligned to the surface normal). */
+ mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
- /* Add the two projected vectors to calculate the final displacement.
- * The Y component is removed. */
- add_v3_v3v3(disp_center, x_disp, z_disp);
+ /* Add the two projected vectors to calculate the final displacement.
+ * The Y component is removed. */
+ add_v3_v3v3(disp_center, x_disp, z_disp);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(disp_center, disp_center, ss->cache->view_normal);
- }
- mul_v3_v3fl(proxy[vd.i], disp_center, fade);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(disp_center, disp_center, ss->cache->view_normal);
+ }
+ mul_v3_v3fl(proxy[vd.i], disp_center, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3961,33 +4007,34 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- if (grab_silhouette) {
- float silhouette_test_dir[3];
- normalize_v3_v3(silhouette_test_dir, grab_delta);
- if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta_symmetry) < 0.0f) {
- mul_v3_fl(silhouette_test_dir, -1.0f);
- }
- float vno[3];
- normal_short_to_float_v3(vno, orig_data.no);
- fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ if (grab_silhouette) {
+ float silhouette_test_dir[3];
+ normalize_v3_v3(silhouette_test_dir, grab_delta);
+ if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta_symmetry) < 0.0f) {
+ mul_v3_fl(silhouette_test_dir, -1.0f);
}
+ float vno[3];
+ normal_short_to_float_v3(vno, orig_data.no);
+ fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f);
+ }
- mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
+ mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4149,13 +4196,14 @@ void SCULPT_flip_v3_by_symm_area(float v[3],
{
for (int i = 0; i < 3; i++) {
ePaintSymmetryFlags symm_it = 1 << i;
- if (symm & symm_it) {
- if (symmarea & symm_it) {
- flip_v3(v, symm_it);
- }
- if (pivot[i] < 0.0f) {
- flip_v3(v, symm_it);
- }
+ if (!(symm & symm_it)) {
+ continue;
+ }
+ if (symmarea & symm_it) {
+ flip_v3(v, symm_it);
+ }
+ if (pivot[i] < 0.0f) {
+ flip_v3(v, symm_it);
}
}
}
@@ -4167,13 +4215,14 @@ void SCULPT_flip_quat_by_symm_area(float quat[3],
{
for (int i = 0; i < 3; i++) {
ePaintSymmetryFlags symm_it = 1 << i;
- if (symm & symm_it) {
- if (symmarea & symm_it) {
- flip_qt(quat, symm_it);
- }
- if (pivot[i] < 0.0f) {
- flip_qt(quat, symm_it);
- }
+ if (!(symm & symm_it)) {
+ continue;
+ }
+ if (symmarea & symm_it) {
+ flip_qt(quat, symm_it);
+ }
+ if (pivot[i] < 0.0f) {
+ flip_qt(quat, symm_it);
}
}
}
@@ -4289,22 +4338,23 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], cono, fade);
+ mul_v3_v3fl(proxy[vd.i], cono, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4368,75 +4418,76 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
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)) {
+ if (!do_elastic && !sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- float fade;
- if (do_elastic) {
- fade = 1.0f;
- }
- else {
- fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- }
+ float fade;
+ if (do_elastic) {
+ fade = 1.0f;
+ }
+ else {
+ fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ }
- mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
+ mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
- /* Negative pinch will inflate, helps maintain volume. */
- if (do_pinch) {
- float delta_pinch_init[3], delta_pinch[3];
+ /* Negative pinch will inflate, helps maintain volume. */
+ if (do_pinch) {
+ float delta_pinch_init[3], delta_pinch[3];
- sub_v3_v3v3(delta_pinch, vd.co, test.location);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal);
- }
+ sub_v3_v3v3(delta_pinch, vd.co, test.location);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal);
+ }
- /* Important to calculate based on the grabbed location
- * (intentionally ignore fade here). */
- add_v3_v3(delta_pinch, grab_delta);
+ /* Important to calculate based on the grabbed location
+ * (intentionally ignore fade here). */
+ add_v3_v3(delta_pinch, grab_delta);
- sculpt_project_v3(spvc, delta_pinch, delta_pinch);
+ sculpt_project_v3(spvc, delta_pinch, delta_pinch);
- copy_v3_v3(delta_pinch_init, delta_pinch);
+ copy_v3_v3(delta_pinch_init, delta_pinch);
- float pinch_fade = pinch * fade;
- /* When reducing, scale reduction back by how close to the center we are,
- * so we don't pinch into nothingness. */
- if (pinch > 0.0f) {
- /* Square to have even less impact for close vertices. */
- pinch_fade *= pow2f(min_ff(1.0f, len_v3(delta_pinch) / ss->cache->radius));
- }
- mul_v3_fl(delta_pinch, 1.0f + pinch_fade);
- sub_v3_v3v3(delta_pinch, delta_pinch_init, delta_pinch);
- add_v3_v3(proxy[vd.i], delta_pinch);
+ float pinch_fade = pinch * fade;
+ /* When reducing, scale reduction back by how close to the center we are,
+ * so we don't pinch into nothingness. */
+ if (pinch > 0.0f) {
+ /* Square to have even less impact for close vertices. */
+ pinch_fade *= pow2f(min_ff(1.0f, len_v3(delta_pinch) / ss->cache->radius));
}
+ mul_v3_fl(delta_pinch, 1.0f + pinch_fade);
+ sub_v3_v3v3(delta_pinch, delta_pinch_init, delta_pinch);
+ add_v3_v3(proxy[vd.i], delta_pinch);
+ }
- if (do_rake_rotation) {
- float delta_rotate[3];
- sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
- add_v3_v3(proxy[vd.i], delta_rotate);
- }
+ if (do_rake_rotation) {
+ float delta_rotate[3];
+ sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
+ add_v3_v3(proxy[vd.i], delta_rotate);
+ }
- if (do_elastic) {
- float disp[3];
- BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
- mul_v3_fl(disp, bstrength * 20.0f);
- if (vd.mask) {
- mul_v3_fl(disp, 1.0f - *vd.mask);
- }
- mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
- copy_v3_v3(proxy[vd.i], disp);
+ if (do_elastic) {
+ float disp[3];
+ BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
+ mul_v3_fl(disp, bstrength * 20.0f);
+ if (vd.mask) {
+ mul_v3_fl(disp, 1.0f - *vd.mask);
}
+ mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
+ copy_v3_v3(proxy[vd.i], disp);
+ }
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4507,22 +4558,23 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], cono, fade);
+ mul_v3_v3fl(proxy[vd.i], cono, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4580,27 +4632,28 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- float vec[3], rot[3][3];
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ float vec[3], rot[3][3];
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
- axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade);
- mul_v3_m3v3(proxy[vd.i], rot, vec);
- add_v3_v3(proxy[vd.i], ss->cache->location);
- sub_v3_v3(proxy[vd.i], orig_data.co);
+ sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
+ axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade);
+ mul_v3_m3v3(proxy[vd.i], rot, vec);
+ add_v3_v3(proxy[vd.i], ss->cache->location);
+ sub_v3_v3(proxy[vd.i], orig_data.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4652,70 +4705,71 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- const int vi = vd.index;
- float *disp_factor;
- if (use_persistent_base) {
- disp_factor = &ss->persistent_base[vi].disp;
- }
- else {
- disp_factor = &ss->cache->layer_displacement_factor[vi];
- }
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ const int vi = vd.index;
+ float *disp_factor;
+ if (use_persistent_base) {
+ disp_factor = &ss->persistent_base[vi].disp;
+ }
+ else {
+ disp_factor = &ss->cache->layer_displacement_factor[vi];
+ }
- /* When using persistent base, the layer brush (holding Control) invert mode resets the
- * height of the layer to 0. This makes possible to clean edges of previously added layers
- * on top of the base. */
- /* The main direction of the layers is inverted using the regular brush strength with the
- * brush direction property. */
- if (use_persistent_base && ss->cache->invert) {
- (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
- ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
- }
- else {
- (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
- }
- if (vd.mask) {
- const float clamp_mask = 1.0f - *vd.mask;
- *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask);
- }
- else {
- *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f);
- }
+ /* When using persistent base, the layer brush (holding Control) invert mode resets the
+ * height of the layer to 0. This makes possible to clean edges of previously added layers
+ * on top of the base. */
+ /* The main direction of the layers is inverted using the regular brush strength with the
+ * brush direction property. */
+ if (use_persistent_base && ss->cache->invert) {
+ (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
+ ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
+ }
+ else {
+ (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
+ }
+ if (vd.mask) {
+ const float clamp_mask = 1.0f - *vd.mask;
+ *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask);
+ }
+ else {
+ *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f);
+ }
- float final_co[3];
- float normal[3];
+ float final_co[3];
+ float normal[3];
- if (use_persistent_base) {
- SCULPT_vertex_persistent_normal_get(ss, vi, normal);
- mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
- }
- else {
- normal_short_to_float_v3(normal, orig_data.no);
- mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
- }
+ if (use_persistent_base) {
+ SCULPT_vertex_persistent_normal_get(ss, vi, normal);
+ mul_v3_fl(normal, brush->height);
+ madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
+ }
+ else {
+ normal_short_to_float_v3(normal, orig_data.no);
+ mul_v3_fl(normal, brush->height);
+ madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
+ }
- float vdisp[3];
- sub_v3_v3v3(vdisp, final_co, vd.co);
- mul_v3_fl(vdisp, fabsf(fade));
- add_v3_v3v3(final_co, vd.co, vdisp);
+ float vdisp[3];
+ sub_v3_v3v3(vdisp, final_co, vd.co);
+ mul_v3_fl(vdisp, fabsf(fade));
+ add_v3_v3v3(final_co, vd.co, vdisp);
- SCULPT_clip(sd, ss, vd.co, final_co);
+ SCULPT_clip(sd, ss, vd.co, final_co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4764,31 +4818,32 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float val[3];
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float val[3];
- if (vd.fno) {
- copy_v3_v3(val, vd.fno);
- }
- else {
- normal_short_to_float_v3(val, vd.no);
- }
+ if (vd.fno) {
+ copy_v3_v3(val, vd.fno);
+ }
+ else {
+ normal_short_to_float_v3(val, vd.no);
+ }
- mul_v3_fl(val, fade * ss->cache->radius);
- mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
+ mul_v3_fl(val, fade * ss->cache->radius);
+ mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4869,30 +4924,31 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float intr[3];
- float val[3];
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float intr[3];
+ float val[3];
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- sub_v3_v3v3(val, intr, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (SCULPT_plane_trim(ss->cache, brush, val)) {
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ mul_v3_v3fl(proxy[vd.i], val, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
@@ -4975,16 +5031,17 @@ static void calc_clay_surface_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float plane_dist = dist_signed_to_plane_v3(vd.co, plane);
- float plane_dist_abs = fabsf(plane_dist);
- if (plane_dist > 0.0f) {
- csd->plane_dist[0] = MIN2(csd->plane_dist[0], plane_dist_abs);
- }
- else {
- csd->plane_dist[1] = MIN2(csd->plane_dist[1], plane_dist_abs);
- }
+ float plane_dist = dist_signed_to_plane_v3(vd.co, plane);
+ float plane_dist_abs = fabsf(plane_dist);
+ if (plane_dist > 0.0f) {
+ csd->plane_dist[0] = MIN2(csd->plane_dist[0], plane_dist_abs);
+ }
+ else {
+ csd->plane_dist[1] = MIN2(csd->plane_dist[1], plane_dist_abs);
}
BKE_pbvh_vertex_iter_end;
}
@@ -5025,28 +5082,30 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float intr[3];
- float val[3];
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- sub_v3_v3v3(val, intr, vd.co);
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ sub_v3_v3v3(val, intr, vd.co);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5143,35 +5202,37 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
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)) {
- if (plane_point_side_flip(vd.co, test.plane_tool, flip)) {
- float intr[3];
- float val[3];
+ if (!SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
+ continue;
+ }
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ if (!plane_point_side_flip(vd.co, test.plane_tool, flip)) {
+ continue;
+ }
- sub_v3_v3v3(val, intr, vd.co);
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
- const float fade = bstrength *
- SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- ss->cache->radius * test.dist,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+ /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ ss->cache->radius * test.dist,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ mul_v3_v3fl(proxy[vd.i], val, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5295,33 +5356,37 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (SCULPT_plane_point_side(vd.co, test.plane_tool)) {
- float intr[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
-
- sub_v3_v3v3(val, intr, vd.co);
-
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ if (!SCULPT_plane_point_side(vd.co, test.plane_tool)) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
+
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5390,33 +5455,37 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (!SCULPT_plane_point_side(vd.co, test.plane_tool)) {
- float intr[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
-
- sub_v3_v3v3(val, intr, vd.co);
-
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ if (SCULPT_plane_point_side(vd.co, test.plane_tool)) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
+
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5501,38 +5570,39 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- mul_v3_m4v3(local_co, mat, vd.co);
- float intr[3], intr_tilt[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- closest_to_plane_normalized_v3(intr_tilt, plane_tilt, vd.co);
-
- /* Mix the deformation of the aligned and the tilted plane based on the brush space vertex
- * coordinates. */
- /* We can also control the mix with a curve if it produces noticeable artifacts in the center
- * of the brush. */
- const float tilt_mix = local_co[1] > 0.0f ? 0.0f : 1.0f;
- interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
- sub_v3_v3v3(val, intr_tilt, vd.co);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float local_co[3];
+ mul_v3_m4v3(local_co, mat, vd.co);
+ float intr[3], intr_tilt[3];
+ float val[3];
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ closest_to_plane_normalized_v3(intr_tilt, plane_tilt, vd.co);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ /* Mix the deformation of the aligned and the tilted plane based on the brush space vertex
+ * coordinates. */
+ /* We can also control the mix with a curve if it produces noticeable artifacts in the center
+ * of the brush. */
+ const float tilt_mix = local_co[1] > 0.0f ? 0.0f : 1.0f;
+ interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
+ sub_v3_v3v3(val, intr_tilt, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5656,22 +5726,23 @@ static void do_gravity_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ 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,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5766,49 +5837,51 @@ static void sculpt_topology_update(Sculpt *sd,
ob, sd, brush, use_original, radius_scale, &totnode);
/* Only act if some verts are inside the brush area. */
- if (totnode) {
- PBVHTopologyUpdateMode mode = 0;
- float location[3];
+ if (totnode == 0) {
+ return;
+ }
- if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
- if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
- mode |= PBVH_Subdivide;
- }
+ PBVHTopologyUpdateMode mode = 0;
+ float location[3];
- if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) {
- mode |= PBVH_Collapse;
- }
+ if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
+ if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
+ mode |= PBVH_Subdivide;
}
- for (n = 0; n < totnode; n++) {
- SCULPT_undo_push_node(ob,
- nodes[n],
- brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
- SCULPT_UNDO_COORDS);
- BKE_pbvh_node_mark_update(nodes[n]);
-
- 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]);
- }
+ if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) {
+ mode |= PBVH_Collapse;
}
+ }
+
+ for (n = 0; n < totnode; n++) {
+ SCULPT_undo_push_node(ob,
+ nodes[n],
+ brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
+ SCULPT_UNDO_COORDS);
+ BKE_pbvh_node_mark_update(nodes[n]);
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- BKE_pbvh_bmesh_update_topology(ss->pbvh,
- mode,
- ss->cache->location,
- ss->cache->view_normal,
- ss->cache->radius,
- (brush->flag & BRUSH_FRONTFACE) != 0,
- (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
+ BKE_pbvh_node_mark_topology_update(nodes[n]);
+ BKE_pbvh_bmesh_node_save_orig(ss->bm, nodes[n]);
}
+ }
- MEM_SAFE_FREE(nodes);
-
- /* Update average stroke position. */
- copy_v3_v3(location, ss->cache->true_location);
- mul_m4_v3(ob->obmat, location);
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_bmesh_update_topology(ss->pbvh,
+ mode,
+ ss->cache->location,
+ ss->cache->view_normal,
+ ss->cache->radius,
+ (brush->flag & BRUSH_FRONTFACE) != 0,
+ (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
}
+
+ MEM_SAFE_FREE(nodes);
+
+ /* Update average stroke position. */
+ copy_v3_v3(location, ss->cache->true_location);
+ mul_m4_v3(ob->obmat, location);
}
static void do_brush_action_task_cb(void *__restrict userdata,
@@ -5914,202 +5987,199 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
}
/* Only act if some verts are inside the brush area. */
- if (totnode) {
- float location[3];
+ if (totnode == 0) {
+ return;
+ }
+ float location[3];
- SculptThreadedTaskData task_data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- };
+ SculptThreadedTaskData task_data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
- if (sculpt_brush_needs_normal(ss, brush)) {
- update_sculpt_normal(sd, ob, nodes, totnode);
- }
+ if (sculpt_brush_needs_normal(ss, brush)) {
+ update_sculpt_normal(sd, ob, nodes, totnode);
+ }
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) {
- update_brush_local_mat(sd, ob);
- }
+ if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) {
+ update_brush_local_mat(sd, ob);
+ }
- if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
- SCULPT_pose_brush_init(sd, ob, ss, brush);
- }
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
+ SCULPT_pose_brush_init(sd, ob, ss, brush);
+ }
- if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
- if (!ss->cache->cloth_sim) {
- ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
- ss, 1.0f, 0.0f, 0.0f, false, true);
- SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
- }
- SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
- SCULPT_cloth_brush_ensure_nodes_constraints(
- sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
+ if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+ if (!ss->cache->cloth_sim) {
+ ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
+ ss, 1.0f, 0.0f, 0.0f, false, true);
+ SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
}
+ SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
+ SCULPT_cloth_brush_ensure_nodes_constraints(
+ sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
+ }
- bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
+ bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
- /* Apply one type of brush action. */
- switch (brush->sculpt_tool) {
- case SCULPT_TOOL_DRAW:
- do_draw_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SMOOTH:
- if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
- SCULPT_do_smooth_brush(sd, ob, nodes, totnode);
- }
- else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
- SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_CREASE:
- do_crease_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_BLOB:
- do_crease_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_PINCH:
- do_pinch_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_INFLATE:
- do_inflate_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_GRAB:
- do_grab_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_ROTATE:
- do_rotate_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SNAKE_HOOK:
- do_snake_hook_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_NUDGE:
- do_nudge_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_THUMB:
- do_thumb_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_LAYER:
- do_layer_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_FLATTEN:
- do_flatten_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY:
- do_clay_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY_STRIPS:
- do_clay_strips_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_MULTIPLANE_SCRAPE:
- SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY_THUMB:
- do_clay_thumb_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_FILL:
- if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
- do_scrape_brush(sd, ob, nodes, totnode);
- }
- else {
- do_fill_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_SCRAPE:
- if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
- do_fill_brush(sd, ob, nodes, totnode);
- }
- else {
- do_scrape_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_MASK:
- do_mask_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_POSE:
- SCULPT_do_pose_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DRAW_SHARP:
- do_draw_sharp_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_ELASTIC_DEFORM:
- do_elastic_deform_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SLIDE_RELAX:
- do_slide_relax_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_BOUNDARY:
- SCULPT_do_boundary_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLOTH:
- SCULPT_do_cloth_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DRAW_FACE_SETS:
- SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DISPLACEMENT_ERASER:
- do_displacement_eraser_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DISPLACEMENT_SMEAR:
- do_displacement_smear_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_PAINT:
- SCULPT_do_paint_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SMEAR:
- SCULPT_do_smear_brush(sd, ob, nodes, totnode);
- break;
- }
-
- if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
- brush->autosmooth_factor > 0) {
- if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
- SCULPT_smooth(sd,
- ob,
- nodes,
- totnode,
- brush->autosmooth_factor * (1.0f - ss->cache->pressure),
- false);
+ /* Apply one type of brush action. */
+ switch (brush->sculpt_tool) {
+ case SCULPT_TOOL_DRAW:
+ do_draw_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SMOOTH:
+ if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
+ SCULPT_do_smooth_brush(sd, ob, nodes, totnode);
+ }
+ else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
+ SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
+ }
+ break;
+ case SCULPT_TOOL_CREASE:
+ do_crease_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_BLOB:
+ do_crease_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_PINCH:
+ do_pinch_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_INFLATE:
+ do_inflate_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_GRAB:
+ do_grab_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_ROTATE:
+ do_rotate_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SNAKE_HOOK:
+ do_snake_hook_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_NUDGE:
+ do_nudge_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_THUMB:
+ do_thumb_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_LAYER:
+ do_layer_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_FLATTEN:
+ do_flatten_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY:
+ do_clay_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY_STRIPS:
+ do_clay_strips_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_MULTIPLANE_SCRAPE:
+ SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY_THUMB:
+ do_clay_thumb_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_FILL:
+ if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
+ do_scrape_brush(sd, ob, nodes, totnode);
}
else {
- SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
+ do_fill_brush(sd, ob, nodes, totnode);
}
- }
+ break;
+ case SCULPT_TOOL_SCRAPE:
+ if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
+ do_fill_brush(sd, ob, nodes, totnode);
+ }
+ else {
+ do_scrape_brush(sd, ob, nodes, totnode);
+ }
+ break;
+ case SCULPT_TOOL_MASK:
+ do_mask_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_POSE:
+ SCULPT_do_pose_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DRAW_SHARP:
+ do_draw_sharp_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_ELASTIC_DEFORM:
+ do_elastic_deform_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SLIDE_RELAX:
+ do_slide_relax_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_BOUNDARY:
+ SCULPT_do_boundary_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLOTH:
+ SCULPT_do_cloth_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DRAW_FACE_SETS:
+ SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DISPLACEMENT_ERASER:
+ do_displacement_eraser_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DISPLACEMENT_SMEAR:
+ do_displacement_smear_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_PAINT:
+ SCULPT_do_paint_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SMEAR:
+ SCULPT_do_smear_brush(sd, ob, nodes, totnode);
+ break;
+ }
- if (sculpt_brush_use_topology_rake(ss, brush)) {
- bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+ if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
+ brush->autosmooth_factor > 0) {
+ if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
+ SCULPT_smooth(
+ sd, ob, nodes, totnode, brush->autosmooth_factor * (1.0f - ss->cache->pressure), false);
}
-
- /* 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,
- SCULPT_TOOL_DRAW_FACE_SETS,
- SCULPT_TOOL_BOUNDARY)) {
- do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
+ else {
+ SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
}
+ }
- if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
- if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
- SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
- SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
- }
+ if (sculpt_brush_use_topology_rake(ss, brush)) {
+ bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+ }
+
+ /* 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,
+ SCULPT_TOOL_DRAW_FACE_SETS,
+ SCULPT_TOOL_BOUNDARY)) {
+ do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
+ }
+
+ if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+ if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
+ SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
+ SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
}
+ }
- MEM_SAFE_FREE(nodes);
+ MEM_SAFE_FREE(nodes);
- /* Update average stroke position. */
- copy_v3_v3(location, ss->cache->true_location);
- mul_m4_v3(ob->obmat, location);
+ /* Update average stroke position. */
+ copy_v3_v3(location, ss->cache->true_location);
+ mul_m4_v3(ob->obmat, location);
- add_v3_v3(ups->average_stroke_accum, location);
- ups->average_stroke_counter++;
- /* Update last stroke position. */
- ups->last_stroke_valid = true;
- }
+ add_v3_v3(ups->average_stroke_accum, location);
+ ups->average_stroke_counter++;
+ /* Update last stroke position. */
+ ups->last_stroke_valid = true;
}
/* Flush displacement from deformed PBVH vertex to original mesh. */
@@ -6199,22 +6269,22 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
PBVHNode **nodes;
int totnode;
- BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
-
- /* First line is tools that don't support proxies. */
- if (ss->cache->supports_gravity || (sculpt_tool_is_proxy_used(brush->sculpt_tool) == false)) {
- SculptThreadedTaskData data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- };
-
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
+ if (!ss->cache->supports_gravity && sculpt_tool_is_proxy_used(brush->sculpt_tool)) {
+ /* First line is tools that don't support proxies. */
+ return;
}
+ BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
MEM_SAFE_FREE(nodes);
}
@@ -6235,12 +6305,14 @@ static void sculpt_update_keyblock(Object *ob)
vertCos = BKE_pbvh_vert_coords_alloc(ss->pbvh);
}
- if (vertCos) {
- SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
+ if (!vertCos) {
+ return;
+ }
- if (vertCos != ss->orig_cos) {
- MEM_freeN(vertCos);
- }
+ SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
+
+ if (vertCos != ss->orig_cos) {
+ MEM_freeN(vertCos);
}
}
@@ -6259,10 +6331,12 @@ static void SCULPT_flush_stroke_deform_task_cb(void *__restrict userdata,
{
sculpt_flush_pbvhvert_deform(ob, &vd);
- if (vertCos) {
- int index = vd.vert_indices[vd.i];
- copy_v3_v3(vertCos[index], ss->orig_cos[index]);
+ if (!vertCos) {
+ continue;
}
+
+ int index = vd.vert_indices[vd.i];
+ copy_v3_v3(vertCos[index], ss->orig_cos[index]);
}
BKE_pbvh_vertex_iter_end;
}
@@ -6490,17 +6564,18 @@ static void do_symmetrical_brush_actions(Sculpt *sd,
/* `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 (int i = 0; i <= symm; i++) {
- if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
- cache->mirror_symmetry_pass = i;
- cache->radial_symmetry_pass = 0;
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ cache->mirror_symmetry_pass = i;
+ cache->radial_symmetry_pass = 0;
- SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
- do_tiled(sd, ob, brush, ups, action);
+ SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
+ do_tiled(sd, ob, brush, ups, action);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather);
- }
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather);
}
}
@@ -6668,22 +6743,25 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
- if (md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
- MirrorModifierData *mmd = (MirrorModifierData *)md;
-
- if (mmd->flag & MOD_MIR_CLIPPING) {
- /* Check each axis for mirroring. */
- for (int i = 0; i < 3; i++) {
- if (mmd->flag & (MOD_MIR_AXIS_X << i)) {
- /* Enable sculpt clipping. */
- ss->cache->flag |= CLIP_X << i;
-
- /* Update the clip tolerance. */
- if (mmd->tolerance > ss->cache->clip_tolerance[i]) {
- ss->cache->clip_tolerance[i] = mmd->tolerance;
- }
- }
- }
+ if (!(md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime))) {
+ continue;
+ }
+ MirrorModifierData *mmd = (MirrorModifierData *)md;
+
+ if (!(mmd->flag & MOD_MIR_CLIPPING)) {
+ continue;
+ }
+ /* Check each axis for mirroring. */
+ for (int i = 0; i < 3; i++) {
+ if (!(mmd->flag & (MOD_MIR_AXIS_X << i))) {
+ continue;
+ }
+ /* Enable sculpt clipping. */
+ ss->cache->flag |= CLIP_X << i;
+
+ /* Update the clip tolerance. */
+ if (mmd->tolerance > ss->cache->clip_tolerance[i]) {
+ ss->cache->clip_tolerance[i] = mmd->tolerance;
}
}
}
@@ -6926,150 +7004,151 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
};
int tool = brush->sculpt_tool;
- if (ELEM(tool,
- SCULPT_TOOL_PAINT,
- SCULPT_TOOL_GRAB,
- SCULPT_TOOL_ELASTIC_DEFORM,
- SCULPT_TOOL_CLOTH,
- SCULPT_TOOL_NUDGE,
- SCULPT_TOOL_CLAY_STRIPS,
- SCULPT_TOOL_PINCH,
- SCULPT_TOOL_MULTIPLANE_SCRAPE,
- SCULPT_TOOL_CLAY_THUMB,
- SCULPT_TOOL_SNAKE_HOOK,
- SCULPT_TOOL_POSE,
- SCULPT_TOOL_BOUNDARY,
- SCULPT_TOOL_THUMB) ||
- sculpt_brush_use_topology_rake(ss, brush)) {
- float grab_location[3], imat[4][4], delta[3], loc[3];
+ if (!ELEM(tool,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ELASTIC_DEFORM,
+ SCULPT_TOOL_CLOTH,
+ SCULPT_TOOL_NUDGE,
+ SCULPT_TOOL_CLAY_STRIPS,
+ SCULPT_TOOL_PINCH,
+ SCULPT_TOOL_MULTIPLANE_SCRAPE,
+ SCULPT_TOOL_CLAY_THUMB,
+ SCULPT_TOOL_SNAKE_HOOK,
+ SCULPT_TOOL_POSE,
+ SCULPT_TOOL_BOUNDARY,
+ SCULPT_TOOL_THUMB) &&
+ !sculpt_brush_use_topology_rake(ss, brush)) {
+ return;
+ }
+ float grab_location[3], imat[4][4], delta[3], loc[3];
- if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
- copy_v3_v3(cache->orig_grab_location,
- SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss)));
- }
- else {
- copy_v3_v3(cache->orig_grab_location, cache->true_location);
- }
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
+ copy_v3_v3(cache->orig_grab_location,
+ SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss)));
}
- else if (tool == SCULPT_TOOL_SNAKE_HOOK ||
- (tool == SCULPT_TOOL_CLOTH &&
- brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) {
- add_v3_v3(cache->true_location, cache->grab_delta);
+ else {
+ copy_v3_v3(cache->orig_grab_location, cache->true_location);
}
+ }
+ else if (tool == SCULPT_TOOL_SNAKE_HOOK ||
+ (tool == SCULPT_TOOL_CLOTH &&
+ brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) {
+ add_v3_v3(cache->true_location, cache->grab_delta);
+ }
- /* Compute 3d coordinate at same z from original location + mouse. */
- mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
- ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mouse, grab_location);
+ /* Compute 3d coordinate at same z from original location + mouse. */
+ mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
+ ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mouse, 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);
- 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);
- 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);
- mul_mat3_m4_v3(imat, cache->grab_delta);
+ /* 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);
+ 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);
+ sub_v3_v3v3(cache->grab_delta, grab_location, orig);
}
else {
- /* Use for 'Brush.topology_rake_factor'. */
sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
}
+ invert_m4_m4(imat, ob->obmat);
+ mul_mat3_m4_v3(imat, cache->grab_delta);
}
else {
- zero_v3(cache->grab_delta);
+ /* Use for 'Brush.topology_rake_factor'. */
+ sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
}
+ }
+ else {
+ zero_v3(cache->grab_delta);
+ }
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal);
- }
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal);
+ }
- copy_v3_v3(cache->old_grab_location, grab_location);
+ copy_v3_v3(cache->old_grab_location, grab_location);
- if (tool == SCULPT_TOOL_GRAB) {
- if (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
- copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
- }
- else {
- copy_v3_v3(cache->anchored_location, cache->true_location);
- }
+ if (tool == SCULPT_TOOL_GRAB) {
+ if (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
}
- else if (tool == SCULPT_TOOL_ELASTIC_DEFORM || SCULPT_is_cloth_deform_brush(brush)) {
+ else {
copy_v3_v3(cache->anchored_location, cache->true_location);
}
- else if (tool == SCULPT_TOOL_THUMB) {
- copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
- }
+ }
+ else if (tool == SCULPT_TOOL_ELASTIC_DEFORM || SCULPT_is_cloth_deform_brush(brush)) {
+ copy_v3_v3(cache->anchored_location, cache->true_location);
+ }
+ else if (tool == SCULPT_TOOL_THUMB) {
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
+ }
- if (sculpt_needs_delta_from_anchored_origin(brush)) {
- /* Location stays the same for finding vertices in brush radius. */
- copy_v3_v3(cache->true_location, cache->orig_grab_location);
+ if (sculpt_needs_delta_from_anchored_origin(brush)) {
+ /* Location stays the same for finding vertices in brush radius. */
+ copy_v3_v3(cache->true_location, cache->orig_grab_location);
- ups->draw_anchored = true;
- copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
- ups->anchored_size = ups->pixel_radius;
- }
+ ups->draw_anchored = true;
+ copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
+ ups->anchored_size = ups->pixel_radius;
+ }
- /* Handle 'rake' */
- cache->is_rake_rotation_valid = false;
+ /* Handle 'rake' */
+ cache->is_rake_rotation_valid = false;
- invert_m4_m4(imat, ob->obmat);
- mul_mat3_m4_v3(imat, grab_location);
+ invert_m4_m4(imat, ob->obmat);
+ mul_mat3_m4_v3(imat, grab_location);
- if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- copy_v3_v3(cache->rake_data.follow_co, grab_location);
- }
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ copy_v3_v3(cache->rake_data.follow_co, grab_location);
+ }
- if (sculpt_brush_needs_rake_rotation(brush)) {
- cache->rake_data.follow_dist = cache->radius * SCULPT_RAKE_BRUSH_FACTOR;
+ if (!sculpt_brush_needs_rake_rotation(brush)) {
+ return;
+ }
+ cache->rake_data.follow_dist = cache->radius * SCULPT_RAKE_BRUSH_FACTOR;
- if (!is_zero_v3(cache->grab_delta)) {
- const float eps = 0.00001f;
+ if (!is_zero_v3(cache->grab_delta)) {
+ const float eps = 0.00001f;
- float v1[3], v2[3];
+ float v1[3], v2[3];
- copy_v3_v3(v1, cache->rake_data.follow_co);
- copy_v3_v3(v2, cache->rake_data.follow_co);
- sub_v3_v3(v2, cache->grab_delta);
+ copy_v3_v3(v1, cache->rake_data.follow_co);
+ copy_v3_v3(v2, cache->rake_data.follow_co);
+ sub_v3_v3(v2, cache->grab_delta);
- sub_v3_v3(v1, grab_location);
- sub_v3_v3(v2, grab_location);
+ sub_v3_v3(v1, grab_location);
+ sub_v3_v3(v2, grab_location);
- if ((normalize_v3(v2) > eps) && (normalize_v3(v1) > eps) &&
- (len_squared_v3v3(v1, v2) > eps)) {
- const float rake_dist_sq = len_squared_v3v3(cache->rake_data.follow_co, grab_location);
- const float rake_fade = (rake_dist_sq > square_f(cache->rake_data.follow_dist)) ?
- 1.0f :
- sqrtf(rake_dist_sq) / cache->rake_data.follow_dist;
+ if ((normalize_v3(v2) > eps) && (normalize_v3(v1) > eps) && (len_squared_v3v3(v1, v2) > eps)) {
+ const float rake_dist_sq = len_squared_v3v3(cache->rake_data.follow_co, grab_location);
+ const float rake_fade = (rake_dist_sq > square_f(cache->rake_data.follow_dist)) ?
+ 1.0f :
+ sqrtf(rake_dist_sq) / cache->rake_data.follow_dist;
- float axis[3], angle;
- float tquat[4];
+ float axis[3], angle;
+ float tquat[4];
- rotation_between_vecs_to_quat(tquat, v1, v2);
+ rotation_between_vecs_to_quat(tquat, v1, v2);
- /* Use axis-angle to scale rotation since the factor may be above 1. */
- quat_to_axis_angle(axis, &angle, tquat);
- normalize_v3(axis);
+ /* Use axis-angle to scale rotation since the factor may be above 1. */
+ quat_to_axis_angle(axis, &angle, tquat);
+ normalize_v3(axis);
- angle *= brush->rake_factor * rake_fade;
- axis_angle_normalized_to_quat(cache->rake_rotation, axis, angle);
- cache->is_rake_rotation_valid = true;
- }
- }
- sculpt_rake_data_update(&cache->rake_data, grab_location);
+ angle *= brush->rake_factor * rake_fade;
+ axis_angle_normalized_to_quat(cache->rake_rotation, axis, angle);
+ cache->is_rake_rotation_valid = true;
}
}
+ sculpt_rake_data_update(&cache->rake_data, grab_location);
}
static void sculpt_update_cache_paint_variants(StrokeCache *cache, const Brush *brush)
@@ -7257,71 +7336,73 @@ void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *b
static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
{
- if (BKE_pbvh_node_get_tmin(node) < *tmin) {
- SculptRaycastData *srd = data_v;
- float(*origco)[3] = NULL;
- bool use_origco = false;
+ if (BKE_pbvh_node_get_tmin(node) >= *tmin) {
+ return;
+ }
+ SculptRaycastData *srd = data_v;
+ float(*origco)[3] = NULL;
+ bool use_origco = false;
- if (srd->original && srd->ss->cache) {
- if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
- use_origco = true;
- }
- else {
- /* Intersect with coordinates from before we started stroke. */
- SculptUndoNode *unode = SCULPT_undo_get_node(node);
- origco = (unode) ? unode->co : NULL;
- use_origco = origco ? true : false;
- }
+ if (srd->original && srd->ss->cache) {
+ if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
+ use_origco = true;
}
-
- if (BKE_pbvh_node_raycast(srd->ss->pbvh,
- node,
- origco,
- use_origco,
- srd->ray_start,
- srd->ray_normal,
- &srd->isect_precalc,
- &srd->depth,
- &srd->active_vertex_index,
- &srd->active_face_grid_index,
- srd->face_normal)) {
- srd->hit = true;
- *tmin = srd->depth;
+ else {
+ /* Intersect with coordinates from before we started stroke. */
+ SculptUndoNode *unode = SCULPT_undo_get_node(node);
+ origco = (unode) ? unode->co : NULL;
+ use_origco = origco ? true : false;
}
}
+
+ if (BKE_pbvh_node_raycast(srd->ss->pbvh,
+ node,
+ origco,
+ use_origco,
+ srd->ray_start,
+ srd->ray_normal,
+ &srd->isect_precalc,
+ &srd->depth,
+ &srd->active_vertex_index,
+ &srd->active_face_grid_index,
+ srd->face_normal)) {
+ srd->hit = true;
+ *tmin = srd->depth;
+ }
}
static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *tmin)
{
- if (BKE_pbvh_node_get_tmin(node) < *tmin) {
- SculptFindNearestToRayData *srd = data_v;
- float(*origco)[3] = NULL;
- bool use_origco = false;
+ if (BKE_pbvh_node_get_tmin(node) >= *tmin) {
+ return;
+ }
+ SculptFindNearestToRayData *srd = data_v;
+ float(*origco)[3] = NULL;
+ bool use_origco = false;
- if (srd->original && srd->ss->cache) {
- if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
- use_origco = true;
- }
- else {
- /* Intersect with coordinates from before we started stroke. */
- SculptUndoNode *unode = SCULPT_undo_get_node(node);
- origco = (unode) ? unode->co : NULL;
- use_origco = origco ? true : false;
- }
+ if (srd->original && srd->ss->cache) {
+ if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
+ use_origco = true;
}
-
- if (BKE_pbvh_node_find_nearest_to_ray(srd->ss->pbvh,
- node,
- origco,
- use_origco,
- srd->ray_start,
- srd->ray_normal,
- &srd->depth,
- &srd->dist_sq_to_ray)) {
- srd->hit = true;
- *tmin = srd->dist_sq_to_ray;
+ else {
+ /* Intersect with coordinates from before we started stroke. */
+ SculptUndoNode *unode = SCULPT_undo_get_node(node);
+ origco = (unode) ? unode->co : NULL;
+ use_origco = origco ? true : false;
}
}
+
+ if (BKE_pbvh_node_find_nearest_to_ray(srd->ss->pbvh,
+ node,
+ origco,
+ use_origco,
+ srd->ray_start,
+ srd->ray_normal,
+ &srd->depth,
+ &srd->dist_sq_to_ray)) {
+ srd->hit = true;
+ *tmin = srd->dist_sq_to_ray;
+ }
}
float SCULPT_raycast_init(ViewContext *vc,
@@ -7546,26 +7627,30 @@ bool SCULPT_stroke_get_location(bContext *C, float out[3], const float mouse[2])
}
}
- if (!hit) {
- if (ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) {
- SculptFindNearestToRayData srd = {
- .original = original,
- .ss = ob->sculpt,
- .hit = false,
- .ray_start = ray_start,
- .ray_normal = ray_normal,
- .depth = FLT_MAX,
- .dist_sq_to_ray = FLT_MAX,
- };
- BKE_pbvh_find_nearest_to_ray(
- ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original);
- if (srd.hit) {
- hit = true;
- copy_v3_v3(out, ray_normal);
- mul_v3_fl(out, srd.depth);
- add_v3_v3(out, ray_start);
- }
- }
+ if (hit) {
+ return hit;
+ }
+
+ if (!ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) {
+ return hit;
+ }
+
+ SculptFindNearestToRayData srd = {
+ .original = original,
+ .ss = ob->sculpt,
+ .hit = false,
+ .ray_start = ray_start,
+ .ray_normal = ray_normal,
+ .depth = FLT_MAX,
+ .dist_sq_to_ray = FLT_MAX,
+ };
+ BKE_pbvh_find_nearest_to_ray(
+ ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original);
+ if (srd.hit) {
+ hit = true;
+ copy_v3_v3(out, ray_normal);
+ mul_v3_fl(out, srd.depth);
+ add_v3_v3(out, ray_start);
}
return hit;
@@ -7748,19 +7833,20 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
bScreen *screen = WM_window_get_active_screen(win);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
SpaceLink *sl = area->spacedata.first;
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *)sl;
- if (v3d != current_v3d) {
- need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, v3d);
- }
+ 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) {
- ED_region_tag_redraw(region);
- }
+ /* 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) {
+ ED_region_tag_redraw(region);
}
}
}
@@ -7920,55 +8006,56 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
/* Finished. */
- if (ss->cache) {
- UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
- Brush *brush = BKE_paint_brush(&sd->paint);
- BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
- ups->draw_inverted = false;
+ if (!ss->cache) {
+ sculpt_brush_exit_tex(sd);
+ return;
+ }
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
+ ups->draw_inverted = false;
- SCULPT_stroke_modifiers_check(C, ob, brush);
+ SCULPT_stroke_modifiers_check(C, ob, brush);
- /* Alt-Smooth. */
- if (ss->cache->alt_smooth) {
- if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
- brush->mask_tool = ss->cache->saved_mask_brush_tool;
- }
- else if (ELEM(brush->sculpt_tool,
- SCULPT_TOOL_SLIDE_RELAX,
- SCULPT_TOOL_DRAW_FACE_SETS,
- SCULPT_TOOL_PAINT,
- SCULPT_TOOL_SMEAR)) {
- /* Do nothing. */
- }
- else {
- BKE_brush_size_set(scene, brush, ss->cache->saved_smooth_size);
- brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, ss->cache->saved_active_brush_name);
- if (brush) {
- BKE_paint_brush_set(&sd->paint, brush);
- }
- }
+ /* Alt-Smooth. */
+ if (ss->cache->alt_smooth) {
+ if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
+ brush->mask_tool = ss->cache->saved_mask_brush_tool;
}
-
- if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
- SCULPT_automasking_cache_free(ss->cache->automasking);
+ else if (ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_SLIDE_RELAX,
+ SCULPT_TOOL_DRAW_FACE_SETS,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_SMEAR)) {
+ /* Do nothing. */
}
+ else {
+ BKE_brush_size_set(scene, brush, ss->cache->saved_smooth_size);
+ brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, ss->cache->saved_active_brush_name);
+ if (brush) {
+ BKE_paint_brush_set(&sd->paint, brush);
+ }
+ }
+ }
- BKE_pbvh_node_color_buffer_free(ss->pbvh);
- SCULPT_cache_free(ss->cache);
- ss->cache = NULL;
+ if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
+ SCULPT_automasking_cache_free(ss->cache->automasking);
+ }
- SCULPT_undo_push_end();
+ BKE_pbvh_node_color_buffer_free(ss->pbvh);
+ SCULPT_cache_free(ss->cache);
+ ss->cache = NULL;
- if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
- SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
- }
- else {
- SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
- }
+ SCULPT_undo_push_end();
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
+ }
+ else {
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
}
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
sculpt_brush_exit_tex(sd);
}
@@ -8090,21 +8177,22 @@ 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) {
- SCULPT_vertex_random_access_ensure(ss);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
+ if (!ss) {
+ 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);
+ MEM_SAFE_FREE(ss->persistent_base);
- const int totvert = SCULPT_vertex_count_get(ss);
- ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
- "layer persistent base");
+ 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++) {
- copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
- SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
- ss->persistent_base[i].disp = 0.0f;
- }
+ for (int i = 0; i < totvert; i++) {
+ copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
+ SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
+ ss->persistent_base[i].disp = 0.0f;
}
return OPERATOR_FINISHED;
@@ -8564,12 +8652,13 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
totpoints++;
ss->preview_vert_index_list[totpoints] = to_v;
totpoints++;
- if (!BLI_BITMAP_TEST(visited_vertices, to_v)) {
- BLI_BITMAP_ENABLE(visited_vertices, to_v);
- const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
- if (len_squared_v3v3(brush_co, co) < radius * radius) {
- BLI_gsqueue_push(not_visited_vertices, &to_v);
- }
+ if (BLI_BITMAP_TEST(visited_vertices, to_v)) {
+ continue;
+ }
+ BLI_BITMAP_ENABLE(visited_vertices, to_v);
+ const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
+ if (len_squared_v3v3(brush_co, co) < radius * radius) {
+ BLI_gsqueue_push(not_visited_vertices, &to_v);
}
}
}
@@ -8993,7 +9082,7 @@ void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist)
for (int i = 0; i < totvert; i++) {
const int from_v = i;
- /* This vertex does not have a fake neighbor yet, seach one for it. */
+ /* This vertex does not have a fake neighbor yet, search one for it. */
if (ss->fake_neighbors.fake_neighbor_index[from_v] == FAKE_NEIGHBOR_NONE) {
const int to_v = SCULPT_fake_neighbor_search(sd, ob, from_v, max_dist);
if (to_v != -1) {
@@ -9099,11 +9188,12 @@ static void do_mask_by_color_contiguous_update_nodes_cb(
const float current_mask = *vd.mask;
const float new_mask = data->mask_by_color_floodfill[vd.index];
*vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
- if (current_mask != *vd.mask) {
- update_node = true;
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (current_mask == *vd.mask) {
+ continue;
+ }
+ update_node = true;
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -9206,11 +9296,12 @@ static void do_mask_by_color_task_cb(void *__restrict userdata,
const float new_mask = sculpt_mask_by_color_delta_get(active_color, vd.col, threshold, invert);
*vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
- if (current_mask != *vd.mask) {
- update_node = true;
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (current_mask == *vd.mask) {
+ continue;
+ }
+ update_node = true;
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender/editors/sculpt_paint/sculpt_automasking.c
index bb68ec56b25..5f5fb51d75f 100644
--- a/source/blender/editors/sculpt_paint/sculpt_automasking.c
+++ b/source/blender/editors/sculpt_paint/sculpt_automasking.c
@@ -298,24 +298,26 @@ float *SCULPT_boundary_automasking_init(Object *ob,
for (int propagation_it = 0; propagation_it < propagation_steps; propagation_it++) {
for (int i = 0; i < totvert; i++) {
- if (edge_distance[i] == EDGE_DISTANCE_INF) {
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
- if (edge_distance[ni.index] == propagation_it) {
- edge_distance[i] = propagation_it + 1;
- }
+ if (edge_distance[i] != EDGE_DISTANCE_INF) {
+ continue;
+ }
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
+ if (edge_distance[ni.index] == propagation_it) {
+ edge_distance[i] = propagation_it + 1;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
}
for (int i = 0; i < totvert; i++) {
- if (edge_distance[i] != EDGE_DISTANCE_INF) {
- 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);
+ if (edge_distance[i] == EDGE_DISTANCE_INF) {
+ continue;
}
+ 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);
}
MEM_SAFE_FREE(edge_distance);
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index 0cfb6f17adb..fca19c04b98 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -227,19 +227,19 @@ static bool boundary_floodfill_cb(
{
BoundaryFloodFillData *data = userdata;
SculptBoundary *boundary = data->boundary;
- if (SCULPT_vertex_is_boundary(ss, to_v)) {
- const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
- SCULPT_vertex_co_get(ss, to_v));
- const float distance_boundary_to_dst = boundary->distance ?
- boundary->distance[from_v] + edge_len :
- 0.0f;
- sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
- if (!is_duplicate) {
- sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
- }
- return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
+ if (!SCULPT_vertex_is_boundary(ss, to_v)) {
+ return false;
+ }
+ const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
+ SCULPT_vertex_co_get(ss, to_v));
+ const float distance_boundary_to_dst = boundary->distance ?
+ boundary->distance[from_v] + edge_len :
+ 0.0f;
+ sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
+ if (!is_duplicate) {
+ sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
}
- return false;
+ return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
}
static void sculpt_boundary_indices_init(SculptSession *ss,
@@ -360,49 +360,50 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const bool is_visible = SCULPT_vertex_visible_get(ss, ni.index);
- if (is_visible &&
- boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) {
- boundary->edit_info[ni.index].original_vertex =
- boundary->edit_info[from_v].original_vertex;
+ if (!is_visible ||
+ boundary->edit_info[ni.index].num_propagation_steps != BOUNDARY_STEPS_NONE) {
+ continue;
+ }
+ boundary->edit_info[ni.index].original_vertex =
+ boundary->edit_info[from_v].original_vertex;
- BLI_BITMAP_ENABLE(visited_vertices, ni.index);
+ BLI_BITMAP_ENABLE(visited_vertices, ni.index);
- if (ni.is_duplicate) {
- /* Grids duplicates handling. */
- boundary->edit_info[ni.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps;
- }
- else {
- boundary->edit_info[ni.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps + 1;
-
- BLI_gsqueue_push(next_iteration, &ni.index);
-
- /* When copying the data to the neighbor for the next iteration, it has to be copied to
- * all its duplicates too. This is because it is not possible to know if the updated
- * neighbor or one if its uninitialized duplicates is going to come first in order to
- * copy the data in the from_v neighbor iterator. */
- if (has_duplicates) {
- SculptVertexNeighborIter ni_duplis;
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
- if (ni_duplis.is_duplicate) {
- boundary->edit_info[ni_duplis.index].original_vertex =
- boundary->edit_info[from_v].original_vertex;
- boundary->edit_info[ni_duplis.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps + 1;
- }
+ if (ni.is_duplicate) {
+ /* Grids duplicates handling. */
+ boundary->edit_info[ni.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps;
+ }
+ else {
+ boundary->edit_info[ni.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps + 1;
+
+ BLI_gsqueue_push(next_iteration, &ni.index);
+
+ /* When copying the data to the neighbor for the next iteration, it has to be copied to
+ * all its duplicates too. This is because it is not possible to know if the updated
+ * neighbor or one if its uninitialized duplicates is going to come first in order to
+ * copy the data in the from_v neighbor iterator. */
+ if (has_duplicates) {
+ SculptVertexNeighborIter ni_duplis;
+ SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
+ if (ni_duplis.is_duplicate) {
+ boundary->edit_info[ni_duplis.index].original_vertex =
+ boundary->edit_info[from_v].original_vertex;
+ boundary->edit_info[ni_duplis.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps + 1;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
+ }
- /* Check the distance using the vertex that was propagated from the initial vertex that
- * was used to initialize the boundary. */
- if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
- boundary->pivot_vertex = ni.index;
- copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
- accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
- SCULPT_vertex_co_get(ss, ni.index));
- }
+ /* Check the distance using the vertex that was propagated from the initial vertex that
+ * was used to initialize the boundary. */
+ if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
+ boundary->pivot_vertex = ni.index;
+ copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
+ accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
+ SCULPT_vertex_co_get(ss, ni.index));
}
}
}
@@ -552,28 +553,30 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
totvert, 3 * sizeof(float), "pivot positions");
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
- float dir[3];
- float normal[3];
- SCULPT_vertex_normal_get(ss, i, normal);
- sub_v3_v3v3(dir,
- SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
- SCULPT_vertex_co_get(ss, i));
- cross_v3_v3v3(
- boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
- normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
- copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, i));
+ if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
+ continue;
}
+ float dir[3];
+ float normal[3];
+ SCULPT_vertex_normal_get(ss, i, normal);
+ sub_v3_v3v3(dir,
+ SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
+ SCULPT_vertex_co_get(ss, i));
+ cross_v3_v3v3(
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
+ normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
+ copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
+ SCULPT_vertex_co_get(ss, i));
}
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
- copy_v3_v3(boundary->bend.pivot_positions[i],
- boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
- copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
- boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ continue;
}
+ copy_v3_v3(boundary->bend.pivot_positions[i],
+ boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
+ copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
}
}
@@ -583,19 +586,20 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b
boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions");
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
- sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
- SCULPT_vertex_co_get(ss, i));
- normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
}
+ sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
+ SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
+ SCULPT_vertex_co_get(ss, i));
+ normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
- copy_v3_v3(boundary->slide.directions[i],
- boundary->slide.directions[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ continue;
}
+ copy_v3_v3(boundary->slide.directions[i],
+ boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
}
@@ -662,24 +666,27 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- 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]);
- rotate_v3_v3v3fl(target_co,
- t_orig_co,
- boundary->bend.pivot_rotation_axis[vd.index],
- angle * boundary->edit_info[vd.index].strength_factor * mask * automask);
- add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ 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]);
+ rotate_v3_v3v3fl(target_co,
+ t_orig_co,
+ boundary->bend.pivot_rotation_axis[vd.index],
+ angle * boundary->edit_info[vd.index].strength_factor * mask * automask);
+ add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -708,22 +715,25 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- boundary->slide.directions[vd.index],
- boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
- strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ boundary->slide.directions[vd.index],
+ boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
+ strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -752,24 +762,27 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float normal[3];
- normal_short_to_float_v3(normal, orig_data.no);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- normal,
- boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
- strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float normal[3];
+ normal_short_to_float_v3(normal, orig_data.no);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ normal,
+ boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
+ strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -796,21 +809,24 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- ss->cache->grab_delta_symmetry,
- boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ ss->cache->grab_delta_symmetry,
+ boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -845,24 +861,27 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- 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);
- rotate_v3_v3v3fl(target_co,
- t_orig_co,
- boundary->twist.rotation_axis,
- angle * mask * automask * boundary->edit_info[vd.index].strength_factor);
- add_v3_v3(target_co, boundary->twist.pivot_position);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ 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);
+ rotate_v3_v3v3fl(target_co,
+ t_orig_co,
+ boundary->twist.rotation_axis,
+ angle * mask * automask * boundary->edit_info[vd.index].strength_factor);
+ add_v3_v3(target_co, boundary->twist.pivot_position);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index c97f31fa682..16d10f6d6bb 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -540,97 +540,98 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, vertex_gravity, vd.index);
/* When using the plane falloff mode the falloff is not constrained by the brush radius. */
- if (sculpt_brush_test_sq_fn(&test, current_vertex_location) || use_falloff_plane) {
-
- float dist = sqrtf(test.dist);
+ if (!sculpt_brush_test_sq_fn(&test, current_vertex_location) && !use_falloff_plane) {
+ continue;
+ }
- if (use_falloff_plane) {
- dist = dist_to_plane_v3(current_vertex_location, deform_plane);
- }
+ float dist = sqrtf(test.dist);
- const float fade = sim_factor * bstrength *
- SCULPT_brush_strength_factor(ss,
- brush,
- current_vertex_location,
- dist,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float brush_disp[3];
- float normal[3];
- if (vd.no) {
- normal_short_to_float_v3(normal, vd.no);
- }
- else {
- copy_v3_v3(normal, vd.fno);
- }
+ if (use_falloff_plane) {
+ dist = dist_to_plane_v3(current_vertex_location, deform_plane);
+ }
- switch (brush->cloth_deform_type) {
- case BRUSH_CLOTH_DEFORM_DRAG:
- sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
- normalize_v3(brush_disp);
- mul_v3_v3fl(force, brush_disp, fade);
- break;
- case BRUSH_CLOTH_DEFORM_PUSH:
- /* Invert the fade to push inwards. */
- mul_v3_v3fl(force, offset, -fade);
- break;
- case BRUSH_CLOTH_DEFORM_GRAB:
- madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
- cloth_sim->init_pos[vd.index],
- ss->cache->grab_delta_symmetry,
- fade);
- if (use_falloff_plane) {
- cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
- }
- else {
- cloth_sim->deformation_strength[vd.index] = 1.0f;
- }
- zero_v3(force);
- break;
- case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
- copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
- madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade);
- cloth_sim->deformation_strength[vd.index] = fade;
- zero_v3(force);
- break;
- case BRUSH_CLOTH_DEFORM_PINCH_POINT:
- if (use_falloff_plane) {
- float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
- copy_v3_v3(brush_disp, plane_normal);
- mul_v3_fl(brush_disp, -distance);
- }
- else {
- sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
- }
- normalize_v3(brush_disp);
- mul_v3_v3fl(force, brush_disp, fade);
- break;
- case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
- float disp_center[3];
- float x_disp[3];
- float z_disp[3];
- sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
- normalize_v3(disp_center);
- mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
- mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
- add_v3_v3v3(disp_center, x_disp, z_disp);
- mul_v3_v3fl(force, disp_center, fade);
- } break;
- case BRUSH_CLOTH_DEFORM_INFLATE:
- mul_v3_v3fl(force, normal, fade);
- break;
- case BRUSH_CLOTH_DEFORM_EXPAND:
- cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
- zero_v3(force);
- break;
- }
+ const float fade = sim_factor * bstrength *
+ SCULPT_brush_strength_factor(ss,
+ brush,
+ current_vertex_location,
+ dist,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float brush_disp[3];
+ float normal[3];
+ if (vd.no) {
+ normal_short_to_float_v3(normal, vd.no);
+ }
+ else {
+ copy_v3_v3(normal, vd.fno);
+ }
- cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
+ switch (brush->cloth_deform_type) {
+ case BRUSH_CLOTH_DEFORM_DRAG:
+ sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
+ normalize_v3(brush_disp);
+ mul_v3_v3fl(force, brush_disp, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_PUSH:
+ /* Invert the fade to push inwards. */
+ mul_v3_v3fl(force, offset, -fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_GRAB:
+ madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
+ cloth_sim->init_pos[vd.index],
+ ss->cache->grab_delta_symmetry,
+ fade);
+ if (use_falloff_plane) {
+ cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
+ }
+ else {
+ cloth_sim->deformation_strength[vd.index] = 1.0f;
+ }
+ zero_v3(force);
+ break;
+ case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
+ copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
+ madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade);
+ cloth_sim->deformation_strength[vd.index] = fade;
+ zero_v3(force);
+ break;
+ case BRUSH_CLOTH_DEFORM_PINCH_POINT:
+ if (use_falloff_plane) {
+ float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
+ copy_v3_v3(brush_disp, plane_normal);
+ mul_v3_fl(brush_disp, -distance);
+ }
+ else {
+ sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
+ }
+ normalize_v3(brush_disp);
+ mul_v3_v3fl(force, brush_disp, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
+ float disp_center[3];
+ float x_disp[3];
+ float z_disp[3];
+ sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
+ normalize_v3(disp_center);
+ mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
+ mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
+ add_v3_v3v3(disp_center, x_disp, z_disp);
+ mul_v3_v3fl(force, disp_center, fade);
+ } break;
+ case BRUSH_CLOTH_DEFORM_INFLATE:
+ mul_v3_v3fl(force, normal, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_EXPAND:
+ cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
+ zero_v3(force);
+ break;
}
+
+ cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
}
BKE_pbvh_vertex_iter_end;
}
@@ -644,17 +645,22 @@ static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph)
DEG_ITER_OBJECT_FLAG_DUPLI) {
CollisionModifierData *cmd = (CollisionModifierData *)BKE_modifiers_findby_type(
ob, eModifierType_Collision);
- if (cmd && cmd->bvhtree) {
- if (cache == NULL) {
- cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
- }
+ if (!cmd) {
+ continue;
+ }
- ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
- col->ob = ob;
- col->collmd = cmd;
- collision_move_object(cmd, 1.0, 0.0, true);
- BLI_addtail(cache, col);
+ if (!cmd->bvhtree) {
+ continue;
}
+ if (cache == NULL) {
+ cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+ }
+
+ ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = ob;
+ col->collmd = cmd;
+ collision_move_object(cmd, 1.0, 0.0, true);
+ BLI_addtail(cache, col);
}
DEG_OBJECT_ITER_END;
return cache;
@@ -734,26 +740,27 @@ static void cloth_brush_solve_collision(Object *object,
&col,
raycast_flag);
- if (hit.index != -1) {
-
- float collision_disp[3];
- float movement_disp[3];
- mul_v3_v3fl(collision_disp, hit.no, 0.005f);
- sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
- float friction_plane[4];
- float pos_on_friction_plane[3];
- plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
- closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
- sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
-
- /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
- mul_v3_fl(movement_disp, 0.35f);
-
- copy_v3_v3(cloth_sim->pos[i], hit.co);
- add_v3_v3(cloth_sim->pos[i], movement_disp);
- add_v3_v3(cloth_sim->pos[i], collision_disp);
- mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
+ if (hit.index == -1) {
+ continue;
}
+
+ float collision_disp[3];
+ float movement_disp[3];
+ mul_v3_v3fl(collision_disp, hit.no, 0.005f);
+ sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
+ float friction_plane[4];
+ float pos_on_friction_plane[3];
+ plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
+ closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
+ sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
+
+ /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
+ mul_v3_fl(movement_disp, 0.35f);
+
+ copy_v3_v3(cloth_sim->pos[i], hit.co);
+ add_v3_v3(cloth_sim->pos[i], movement_disp);
+ add_v3_v3(cloth_sim->pos[i], collision_disp);
+ mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
}
}
@@ -784,38 +791,40 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
ss->cache ? cloth_brush_simulation_falloff_get(
brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]) :
1.0f;
- if (sim_factor > 0.0f) {
- int i = vd.index;
- float temp[3];
- copy_v3_v3(temp, cloth_sim->pos[i]);
+ if (sim_factor <= 0.0f) {
+ continue;
+ }
- mul_v3_fl(cloth_sim->acceleration[i], time_step);
+ int i = vd.index;
+ float temp[3];
+ copy_v3_v3(temp, cloth_sim->pos[i]);
- float pos_diff[3];
- sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
- mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
+ mul_v3_fl(cloth_sim->acceleration[i], time_step);
- const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
- SCULPT_automasking_factor_get(automasking, ss, vd.index);
+ float pos_diff[3];
+ sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
+ mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
- madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
- madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
+ const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
+ SCULPT_automasking_factor_get(automasking, ss, vd.index);
- if (cloth_sim->collider_list != NULL) {
- cloth_brush_solve_collision(data->ob, cloth_sim, i);
- }
+ madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
+ madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
- copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
+ if (cloth_sim->collider_list != NULL) {
+ cloth_brush_solve_collision(data->ob, cloth_sim, i);
+ }
- copy_v3_v3(cloth_sim->prev_pos[i], temp);
- copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
- copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
- copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
+ copy_v3_v3(cloth_sim->prev_pos[i], temp);
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
+ copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c
index aa1d407dc24..ddf7ba1e412 100644
--- a/source/blender/editors/sculpt_paint/sculpt_detail.c
+++ b/source/blender/editors/sculpt_paint/sculpt_detail.c
@@ -24,46 +24,29 @@
#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 "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 "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_view3d.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>
#include <stdlib.h>
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 1fba958d695..df03d2adeaf 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -148,40 +148,42 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
float poly_center[3];
BKE_mesh_calc_poly_center(p, &ss->mloop[p->loopstart], mvert, poly_center);
- if (sculpt_brush_test_sq_fn(&test, poly_center)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- 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 (!sculpt_brush_test_sq_fn(&test, poly_center)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ 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);
}
}
}
else if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- if (fade > 0.05f) {
- SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set);
- }
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ if (fade > 0.05f) {
+ SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set);
}
}
}
@@ -205,7 +207,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const bool relax_face_sets = !(ss->cache->iteration_count % 3 == 0);
- /* This operations needs a stregth tweak as the relax deformation is too weak by default. */
+ /* This operations needs a strength tweak as the relax deformation is too weak by default. */
if (relax_face_sets) {
bstrength *= 2.0f;
}
@@ -214,23 +216,26 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (relax_face_sets != SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
+ continue;
+ }
- SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -313,7 +318,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
const int mode = RNA_enum_get(op->ptr, "mode");
- /* Dyntopo not suported. */
+ /* Dyntopo not supported. */
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
return OPERATOR_CANCELLED;
}
@@ -582,44 +587,49 @@ static void sculpt_face_sets_init_flood_fill(Object *ob,
int next_face_set = 1;
for (int i = 0; i < totfaces; i++) {
- if (!BLI_BITMAP_TEST(visited_faces, i)) {
- GSQueue *queue;
- queue = BLI_gsqueue_new(sizeof(int));
-
- 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) {
- int neighbor_face_index = BM_elem_index_get(f_neighbor);
- if (!BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
- if (test(bm, f, ed, f_neighbor, threshold)) {
- face_sets[neighbor_face_index] = next_face_set;
- BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
- BLI_gsqueue_push(queue, &neighbor_face_index);
- }
- }
- }
+ if (BLI_BITMAP_TEST(visited_faces, i)) {
+ continue;
+ }
+ GSQueue *queue;
+ queue = BLI_gsqueue_new(sizeof(int));
+
+ 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) {
+ continue;
}
+ int neighbor_face_index = BM_elem_index_get(f_neighbor);
+ if (BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
+ continue;
+ }
+ if (!test(bm, f, ed, f_neighbor, threshold)) {
+ continue;
+ }
+
+ face_sets[neighbor_face_index] = next_face_set;
+ BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
+ BLI_gsqueue_push(queue, &neighbor_face_index);
}
}
+ }
- next_face_set += 1;
+ next_face_set += 1;
- BLI_gsqueue_free(queue);
- }
+ BLI_gsqueue_free(queue);
}
MEM_SAFE_FREE(visited_faces);
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index e11894a8c01..3cf6a8cc561 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -553,7 +553,7 @@ static void mesh_filter_sharpen_init(SculptSession *ss,
filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - filter_cache->sharpen_factor[i]);
}
- /* Smooth the calculated factors and directions to remove high frecuency detail. */
+ /* Smooth the calculated factors and directions to remove high frequency detail. */
for (int smooth_iterations = 0;
smooth_iterations < filter_cache->sharpen_curvature_smooth_iterations;
smooth_iterations++) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index d1e17c7e59b..f90cf366ed9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -511,7 +511,7 @@ void SCULPT_boundary_edges_preview_draw(const uint gpuattr,
const float outline_alpha);
void SCULPT_boundary_pivot_line_preview_draw(const uint gpuattr, struct SculptSession *ss);
-/* Multiplane Scrape Brush. */
+/* Multi-plane Scrape Brush. */
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
Brush *brush,
diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
index e47a94dff90..cfc31e1dcdd 100644
--- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
+++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
@@ -88,38 +88,39 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- float normal[3];
- if (vd.no) {
- normal_short_to_float_v3(normal, vd.no);
- }
- else {
- copy_v3_v3(normal, vd.fno);
- }
- mul_v3_m4v3(local_co, mat, vd.co);
- /* Use the brush falloff to weight the sampled normals. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- /* Sample the normal and area of the +X and -X axis individually. */
- if (local_co[0] > 0.0f) {
- madd_v3_v3fl(mssd->area_nos[0], normal, fade);
- add_v3_v3(mssd->area_cos[0], vd.co);
- mssd->area_count[0]++;
- }
- else {
- madd_v3_v3fl(mssd->area_nos[1], normal, fade);
- add_v3_v3(mssd->area_cos[1], vd.co);
- mssd->area_count[1]++;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float local_co[3];
+ float normal[3];
+ if (vd.no) {
+ normal_short_to_float_v3(normal, vd.no);
+ }
+ else {
+ copy_v3_v3(normal, vd.fno);
+ }
+ mul_v3_m4v3(local_co, mat, vd.co);
+ /* Use the brush falloff to weight the sampled normals. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ /* Sample the normal and area of the +X and -X axis individually. */
+ if (local_co[0] > 0.0f) {
+ madd_v3_v3fl(mssd->area_nos[0], normal, fade);
+ add_v3_v3(mssd->area_cos[0], vd.co);
+ mssd->area_count[0]++;
+ }
+ else {
+ madd_v3_v3fl(mssd->area_nos[1], normal, fade);
+ add_v3_v3(mssd->area_cos[1], vd.co);
+ mssd->area_count[1]++;
}
BKE_pbvh_vertex_iter_end;
}
@@ -168,56 +169,61 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- bool deform = false;
-
- mul_v3_m4v3(local_co, mat, vd.co);
-
- if (local_co[0] > 0.0f) {
- deform = !SCULPT_plane_point_side(vd.co, scrape_planes[0]);
- }
- else {
- deform = !SCULPT_plane_point_side(vd.co, scrape_planes[1]);
- }
-
- if (angle < 0.0f) {
- deform = true;
- }
-
- if (deform) {
- float intr[3];
- float val[3];
-
- if (local_co[0] > 0.0f) {
- closest_to_plane_normalized_v3(intr, scrape_planes[0], vd.co);
- }
- else {
- closest_to_plane_normalized_v3(intr, scrape_planes[1], vd.co);
- }
-
- sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- /* 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;
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- len_v3(local_co),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ float local_co[3];
+ bool deform = false;
+
+ mul_v3_m4v3(local_co, mat, vd.co);
+
+ if (local_co[0] > 0.0f) {
+ deform = !SCULPT_plane_point_side(vd.co, scrape_planes[0]);
+ }
+ else {
+ deform = !SCULPT_plane_point_side(vd.co, scrape_planes[1]);
+ }
+
+ if (angle < 0.0f) {
+ deform = true;
+ }
+
+ if (!deform) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+
+ if (local_co[0] > 0.0f) {
+ closest_to_plane_normalized_v3(intr, scrape_planes[0], vd.co);
+ }
+ else {
+ closest_to_plane_normalized_v3(intr, scrape_planes[1], vd.co);
+ }
+
+ sub_v3_v3v3(val, intr, vd.co);
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+ /* 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;
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ len_v3(local_co),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index 39320f3f558..5fdf8415f28 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -87,24 +87,25 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float smooth_color[4];
- SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
- blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float smooth_color[4];
+ SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
+ blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -153,46 +154,49 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
distance_to_stroke_location = sqrtf(test.dist);
}
- if (affect_vertex) {
- float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- distance_to_stroke_location,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- /* Density. */
- float noise = 1.0f;
- const float density = ss->cache->paint_brush.density;
- if (density < 1.0f) {
- const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
- if (hash_noise > density) {
- noise = density * hash_noise;
- fade = fade * noise;
- }
+ if (!affect_vertex) {
+ continue;
+ }
+
+ float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ distance_to_stroke_location,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ /* Density. */
+ float noise = 1.0f;
+ const float density = ss->cache->paint_brush.density;
+ if (density < 1.0f) {
+ const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
+ if (hash_noise > density) {
+ noise = density * hash_noise;
+ fade = fade * noise;
}
+ }
- /* Brush paint color, brush test falloff and flow. */
- float paint_color[4];
- float wet_mix_color[4];
- float buffer_color[4];
+ /* Brush paint color, brush test falloff and flow. */
+ float paint_color[4];
+ float wet_mix_color[4];
+ float buffer_color[4];
- mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
- mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
+ mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
+ mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
- /* Interpolate with the wet_mix color for wet paint mixing. */
- blend_color_interpolate_float(
- 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);
+ /* Interpolate with the wet_mix color for wet paint mixing. */
+ blend_color_interpolate_float(
+ 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. */
+ mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
+
+ IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
- IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
- }
CLAMP4(vd.col, 0.0f, 1.0f);
if (vd.mvert) {
@@ -225,10 +229,12 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- add_v4_v4(swptd->color, vd.col);
- swptd->tot_samples++;
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
}
+
+ add_v4_v4(swptd->color, vd.col);
+ swptd->tot_samples++;
}
BKE_pbvh_vertex_iter_end;
}
@@ -380,59 +386,61 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float current_disp[3];
- float current_disp_norm[3];
- float interp_color[4];
- copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
-
- switch (brush->smear_deform_type) {
- case BRUSH_SMEAR_DEFORM_DRAG:
- sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
- break;
- case BRUSH_SMEAR_DEFORM_PINCH:
- sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
- break;
- case BRUSH_SMEAR_DEFORM_EXPAND:
- sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
- break;
- }
- normalize_v3_v3(current_disp_norm, current_disp);
- mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
-
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
- float vertex_disp[3];
- float vertex_disp_norm[3];
- sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
- const float *neighbor_color = ss->cache->prev_colors[ni.index];
- normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) {
- const float color_interp = clamp_f(
- -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
- float color_mix[4];
- copy_v4_v4(color_mix, neighbor_color);
- mul_v4_fl(color_mix, color_interp * fade);
- blend_color_mix_float(interp_color, interp_color, color_mix);
- }
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float current_disp[3];
+ float current_disp_norm[3];
+ float interp_color[4];
+ copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
+
+ switch (brush->smear_deform_type) {
+ case BRUSH_SMEAR_DEFORM_DRAG:
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ break;
+ case BRUSH_SMEAR_DEFORM_PINCH:
+ sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
+ break;
+ case BRUSH_SMEAR_DEFORM_EXPAND:
+ sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
+ break;
+ }
+ normalize_v3_v3(current_disp_norm, current_disp);
+ mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ float vertex_disp[3];
+ float vertex_disp_norm[3];
+ sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
+ const float *neighbor_color = ss->cache->prev_colors[ni.index];
+ normalize_v3_v3(vertex_disp_norm, vertex_disp);
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
+ continue;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ const float color_interp = clamp_f(
+ -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
+ float color_mix[4];
+ copy_v4_v4(color_mix, neighbor_color);
+ mul_v4_fl(color_mix, color_interp * fade);
+ blend_color_mix_float(interp_color, interp_color, color_mix);
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
+ blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index 1bf9ba60073..a85f805894b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -490,50 +490,52 @@ static bool pose_face_sets_floodfill_cb(
is_vertex_valid = SCULPT_vertex_has_face_set(ss, index, data->current_face_set);
}
- if (is_vertex_valid) {
-
- if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
- data->pose_factor[index] = 1.0f;
- BLI_BITMAP_ENABLE(data->is_weighted, index);
- visit_next = true;
- }
-
- /* Fallback origin accumulation. */
- if (symmetry_check) {
- add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
- data->fallback_count++;
- }
-
- if (symmetry_check && !SCULPT_vertex_has_unique_face_set(ss, index)) {
+ if (!is_vertex_valid) {
+ return visit_next;
+ }
- /* We only add coordinates for calculating the origin when it is possible to go from this
- * vertex to another vertex in a valid face set for the next iteration. */
- bool count_as_boundary = false;
+ if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
+ data->pose_factor[index] = 1.0f;
+ BLI_BITMAP_ENABLE(data->is_weighted, index);
+ visit_next = true;
+ }
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
- int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
+ /* Fallback origin accumulation. */
+ if (symmetry_check) {
+ add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
+ data->fallback_count++;
+ }
- /* Check if we can get a valid face set for the next iteration from this neighbor. */
- if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
- !BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
- if (!data->next_face_set_found) {
- data->next_face_set = next_face_set_candidate;
- data->next_vertex = ni.index;
- data->next_face_set_found = true;
- }
- count_as_boundary = true;
- }
- }
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ if (!symmetry_check || SCULPT_vertex_has_unique_face_set(ss, index)) {
+ return visit_next;
+ }
- /* Origin accumulation. */
- if (count_as_boundary) {
- add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
- data->tot_co++;
+ /* We only add coordinates for calculating the origin when it is possible to go from this
+ * vertex to another vertex in a valid face set for the next iteration. */
+ bool count_as_boundary = false;
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
+ int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
+
+ /* Check if we can get a valid face set for the next iteration from this neighbor. */
+ if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
+ !BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
+ if (!data->next_face_set_found) {
+ data->next_face_set = next_face_set_candidate;
+ data->next_vertex = ni.index;
+ data->next_face_set_found = true;
}
+ count_as_boundary = true;
}
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ /* Origin accumulation. */
+ if (count_as_boundary) {
+ add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
+ data->tot_co++;
+ }
return visit_next;
}
@@ -738,7 +740,7 @@ static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd,
* iteration an the current iteration. */
for (int j = 0; j < totvert; j++) {
ik_chain->segments[i].weights[j] = pose_factor_grow[j] - pose_factor_grow_prev[j];
- /* Store the current grow factor status for the next interation. */
+ /* Store the current grow factor status for the next iteration. */
pose_factor_grow_prev[j] = pose_factor_grow[j];
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 87ee7480c92..4c0795eb0f7 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -231,24 +231,26 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float disp[3];
- madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
- SCULPT_clip(sd, ss, vd.co, disp);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float disp[3];
+ madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
+ SCULPT_clip(sd, ss, vd.co, disp);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -312,33 +314,34 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(
- ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
- vd.index,
- thread_id);
- if (smooth_mask) {
- float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
- val *= fade * bstrength;
- *vd.mask += val;
- CLAMP(*vd.mask, 0.0f, 1.0f);
- }
- else {
- float avg[3], val[3];
- SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
- sub_v3_v3v3(val, avg, vd.co);
- madd_v3_v3v3fl(val, vd.co, val, fade);
- SCULPT_clip(sd, ss, vd.co, val);
- }
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ 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,
+ smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
+ vd.index,
+ thread_id);
+ if (smooth_mask) {
+ float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
+ val *= fade * bstrength;
+ *vd.mask += val;
+ CLAMP(*vd.mask, 0.0f, 1.0f);
+ }
+ else {
+ float avg[3], val[3];
+ SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
+ sub_v3_v3v3(val, avg, vd.co);
+ madd_v3_v3v3fl(val, vd.co, val, fade);
+ SCULPT_clip(sd, ss, vd.co, val);
+ }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -473,32 +476,28 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
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)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float disp[3];
- SCULPT_surface_smooth_laplacian_step(ss,
- disp,
- vd.co,
- ss->cache->surface_smooth_laplacian_disp,
- vd.index,
- orig_data.co,
- alpha);
- madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float disp[3];
+ SCULPT_surface_smooth_laplacian_step(
+ ss, disp, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, orig_data.co, alpha);
+ madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
- BKE_pbvh_vertex_iter_end;
}
+ BKE_pbvh_vertex_iter_end;
}
static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
@@ -519,19 +518,20 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- SCULPT_surface_smooth_displace_step(
- ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
+ 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.mask : 0.0f,
+ vd.index,
+ thread_id);
+ SCULPT_surface_smooth_displace_step(
+ ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
}
BKE_pbvh_vertex_iter_end;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 938080b392d..ec103bd2b98 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -1527,9 +1527,14 @@ static void sculpt_undosys_step_decode_redo(struct bContext *C,
}
}
-static void sculpt_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir, bool UNUSED(is_final))
+static void sculpt_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir dir,
+ bool UNUSED(is_final))
{
+ BLI_assert(dir != STEP_INVALID);
+
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
/* Ensure sculpt mode. */
@@ -1568,10 +1573,10 @@ static void sculpt_undosys_step_decode(
}
SculptUndoStep *us = (SculptUndoStep *)us_p;
- if (dir < 0) {
+ if (dir == STEP_UNDO) {
sculpt_undosys_step_decode_undo(C, depsgraph, us);
}
- else {
+ else if (dir == STEP_REDO) {
sculpt_undosys_step_decode_redo(C, depsgraph, us);
}
}
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 34617804888..85616f6356d 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -31,7 +31,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
@@ -877,7 +876,7 @@ static void SOUND_OT_unpack(wmOperatorType *ot)
/* properties */
RNA_def_enum(
ot->srna, "method", rna_enum_unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack");
- /* XXX, weark!, will fail with library, name collisions */
+ /* XXX: weak!, will fail with library, name collisions */
RNA_def_string(
ot->srna, "id", NULL, MAX_ID_NAME - 2, "Sound Name", "Sound data-block name to unpack");
}
diff --git a/source/blender/editors/space_action/action_buttons.c b/source/blender/editors/space_action/action_buttons.c
index 5e1c205f1d4..dfc3789a26c 100644
--- a/source/blender/editors/space_action/action_buttons.c
+++ b/source/blender/editors/space_action/action_buttons.c
@@ -26,33 +26,10 @@
#include <stdio.h>
#include <string.h>
-#include "DNA_anim_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "BKE_context.h"
-#include "BKE_curve.h"
-#include "BKE_fcurve.h"
#include "BKE_screen.h"
-#include "BKE_unit.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "RNA_access.h"
-
-#include "ED_anim_api.h"
-#include "ED_keyframing.h"
-#include "ED_screen.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
#include "action_intern.h" /* own include */
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index f731fe23b7c..f8389d40831 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -73,7 +73,7 @@
/* ************************************************************************** */
/* POSE MARKERS STUFF */
-/* *************************** Localise Markers ***************************** */
+/* *************************** Localize Markers ***************************** */
/* ensure that there is:
* 1) an active action editor
@@ -322,7 +322,7 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min,
bAnimListElem *ale;
int filter;
- /* NOTE: not bool, since we want prioritise individual channels over expanders */
+ /* NOTE: not bool, since we want prioritize individual channels over expanders. */
short found = 0;
/* get all items - we need to do it this way */
@@ -346,7 +346,7 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min,
found = acf->channel_role;
/* only stop our search when we've found an actual channel
- * - datablock expanders get less priority so that we don't abort prematurely
+ * - data-block expanders get less priority so that we don't abort prematurely
*/
if (found == ACHANNEL_ROLE_CHANNEL) {
break;
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 7422c05511c..7821458d1e5 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -27,9 +27,6 @@
#include "DNA_space_types.h"
#include "ED_anim_api.h"
-#include "ED_markers.h"
-#include "ED_object.h"
-#include "ED_select_utils.h"
#include "ED_transform.h"
#include "action_intern.h"
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index ff0201f9702..722005235d3 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -55,7 +55,6 @@
#include "ED_space_api.h"
#include "ED_time_scrub_ui.h"
-#include "GPU_framebuffer.h"
#include "action_intern.h" /* own include */
/* ******************** default callbacks for action space ***************** */
@@ -305,12 +304,11 @@ static void action_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void action_channel_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_channel_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -356,14 +354,13 @@ static void action_channel_region_listener(wmWindow *UNUSED(win),
}
}
-static void saction_channel_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void saction_channel_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, area->spacedata.first, &ptr);
@@ -401,12 +398,11 @@ static void saction_channel_region_message_subscribe(const struct bContext *UNUS
}
}
-static void action_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -460,14 +456,14 @@ static void action_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void saction_main_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void saction_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, area->spacedata.first, &ptr);
@@ -502,15 +498,14 @@ static void saction_main_region_message_subscribe(const struct bContext *C,
}
/* Now run the general "channels region" one - since channels and main should be in sync */
- saction_channel_region_message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ saction_channel_region_message_subscribe(params);
}
/* editor level listener */
-static void action_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void action_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceAction *saction = (SpaceAction *)area->spacedata.first;
/* context changes */
@@ -660,12 +655,11 @@ static void action_listener(wmWindow *UNUSED(win),
}
}
-static void action_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_header_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
SpaceAction *saction = (SpaceAction *)area->spacedata.first;
/* context changes */
@@ -737,12 +731,11 @@ static void action_buttons_area_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void action_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 10fa2c19919..817760615df 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -70,16 +70,13 @@
#include "io_ops.h"
-/* only call once on startup, storage is global in BKE kernel listbase */
+/* Only called once on startup. storage is global in BKE kernel listbase. */
void ED_spacetypes_init(void)
{
- const ListBase *spacetypes;
- SpaceType *type;
-
- /* UI_UNIT_X is now a variable, is used in some spacetype inits? */
+ /* UI unit is a variable, may be used in some space type inits. */
U.widget_unit = 20;
- /* create space types */
+ /* Create space types. */
ED_spacetype_outliner();
ED_spacetype_view3d();
ED_spacetype_ipo();
@@ -98,9 +95,8 @@ void ED_spacetypes_init(void)
ED_spacetype_clip();
ED_spacetype_statusbar();
ED_spacetype_topbar();
- // ...
- /* register operator types for screen and all spaces */
+ /* Register operator types for screen and all spaces. */
ED_operatortypes_userpref();
ED_operatortypes_workspace();
ED_operatortypes_scene();
@@ -132,7 +128,7 @@ void ED_spacetypes_init(void)
ED_screen_user_menu_register();
- /* gizmo types */
+ /* Gizmo types. */
ED_gizmotypes_button_2d();
ED_gizmotypes_dial_3d();
ED_gizmotypes_move_3d();
@@ -144,10 +140,10 @@ void ED_spacetypes_init(void)
ED_gizmotypes_cage_3d();
ED_gizmotypes_snap_3d();
- /* register types for operators and gizmos */
- spacetypes = BKE_spacetypes_list();
- for (type = spacetypes->first; type; type = type->next) {
- /* init gizmo types first, operator-types need them */
+ /* Register types for operators and gizmos. */
+ const ListBase *spacetypes = BKE_spacetypes_list();
+ LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
+ /* Initialize gizmo types first, operator types need them. */
if (type->gizmos) {
type->gizmos();
}
@@ -159,11 +155,8 @@ void ED_spacetypes_init(void)
void ED_spacemacros_init(void)
{
- const ListBase *spacetypes;
- SpaceType *type;
-
- /* Macros's must go last since they reference other operators.
- * We need to have them go after python operators too */
+ /* Macros must go last since they reference other operators.
+ * They need to be registered after python operators too. */
ED_operatormacros_armature();
ED_operatormacros_mesh();
ED_operatormacros_uvedit();
@@ -180,24 +173,21 @@ void ED_spacemacros_init(void)
ED_operatormacros_paint();
ED_operatormacros_gpencil();
- /* register dropboxes (can use macros) */
- spacetypes = BKE_spacetypes_list();
- for (type = spacetypes->first; type; type = type->next) {
+ /* Register dropboxes (can use macros). */
+ const ListBase *spacetypes = BKE_spacetypes_list();
+ LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
if (type->dropboxes) {
type->dropboxes();
}
}
}
-/* called in wm.c */
-/* keymap definitions are registered only once per WM initialize, usually on file read,
- * using the keymap the actual areas/regions add the handlers */
+/**
+ * \note Keymap definitions are registered only once per WM initialize,
+ * usually on file read, using the keymap the actual areas/regions add the handlers.
+ * \note Called in wm.c. */
void ED_spacetypes_keymap(wmKeyConfig *keyconf)
{
- const ListBase *spacetypes;
- SpaceType *stype;
- ARegionType *atype;
-
ED_keymap_screen(keyconf);
ED_keymap_anim(keyconf);
ED_keymap_animchannels(keyconf);
@@ -219,20 +209,20 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf)
ED_keymap_transform(keyconf);
- spacetypes = BKE_spacetypes_list();
- for (stype = spacetypes->first; stype; stype = stype->next) {
- if (stype->keymap) {
- stype->keymap(keyconf);
+ const ListBase *spacetypes = BKE_spacetypes_list();
+ LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
+ if (type->keymap) {
+ type->keymap(keyconf);
}
- for (atype = stype->regiontypes.first; atype; atype = atype->next) {
- if (atype->keymap) {
- atype->keymap(keyconf);
+ LISTBASE_FOREACH (ARegionType *, region_type, &type->regiontypes) {
+ if (region_type->keymap) {
+ region_type->keymap(keyconf);
}
}
}
}
-/* ********************** custom drawcall api ***************** */
+/* ********************** Custom Draw Call API ***************** */
typedef struct RegionDrawCB {
struct RegionDrawCB *next, *prev;
@@ -261,9 +251,7 @@ void *ED_region_draw_cb_activate(ARegionType *art,
void ED_region_draw_cb_exit(ARegionType *art, void *handle)
{
- RegionDrawCB *rdc;
-
- for (rdc = art->drawcalls.first; rdc; rdc = rdc->next) {
+ LISTBASE_FOREACH (RegionDrawCB *, rdc, &art->drawcalls) {
if (rdc == (RegionDrawCB *)handle) {
BLI_remlink(&art->drawcalls, rdc);
MEM_freeN(rdc);
@@ -274,9 +262,7 @@ void ED_region_draw_cb_exit(ARegionType *art, void *handle)
void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
{
- RegionDrawCB *rdc;
-
- for (rdc = region->type->drawcalls.first; rdc; rdc = rdc->next) {
+ LISTBASE_FOREACH (RegionDrawCB *, rdc, &region->type->drawcalls) {
if (rdc->type == type) {
rdc->draw(C, region, rdc->customdata);
@@ -301,7 +287,7 @@ static void xxx_free(SpaceLink *UNUSED(sl))
{
}
-/* spacetype; init callback for usage, should be redoable */
+/* spacetype; init callback for usage, should be re-doable. */
static void xxx_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
{
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index e2b889bece1..5f347451c4a 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -33,8 +33,6 @@
#include "DNA_armature_types.h"
#include "DNA_brush_types.h"
-#include "DNA_collection_types.h"
-#include "DNA_light_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
@@ -53,7 +51,6 @@
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_screen.h"
-#include "BKE_texture.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 6f743eb1a6b..4847e8738df 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -52,10 +52,7 @@
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
-#include "BKE_scene.h"
-#include "BKE_workspace.h"
#ifdef WITH_FREESTYLE
-# include "BKE_freestyle.h"
#endif
#include "RNA_access.h"
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index e50ca2ec92b..07bc1d42c3f 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -514,12 +514,11 @@ static void buttons_main_region_layout(const bContext *C, ARegion *region)
sbuts->mainbo = sbuts->mainb;
}
-static void buttons_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void buttons_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -567,15 +566,13 @@ static void buttons_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void buttons_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *area,
- ARegion *region,
- struct wmMsgBus *mbus)
+static void buttons_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceProperties *sbuts = area->spacedata.first;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -621,14 +618,12 @@ static void buttons_navigation_bar_region_draw(const bContext *C, ARegion *regio
ED_region_panels_draw(C, region);
}
-static void buttons_navigation_bar_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void buttons_navigation_bar_region_message_subscribe(
+ const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -657,11 +652,10 @@ static void buttons_area_redraw(ScrArea *area, short buttons)
* \{ */
/* reused! */
-static void buttons_area_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void buttons_area_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceProperties *sbuts = area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 81bae26efeb..632f3c5147f 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -46,7 +46,6 @@
#include "DEG_depsgraph.h"
#include "ED_clip.h"
-#include "ED_gpencil.h"
#include "ED_screen.h"
#include "UI_interface.h"
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index bd11a746e11..af1d082d317 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -327,118 +327,18 @@ void ED_clip_update_frame(const Main *mainp, int cfra)
}
}
-static bool selected_tracking_boundbox(SpaceClip *sc, float min[2], float max[2])
+bool ED_clip_view_selection(const bContext *C, ARegion *UNUSED(region), bool fit)
{
- MovieClip *clip = ED_space_clip_get_clip(sc);
- MovieTrackingTrack *track;
- int width, height;
- bool ok = false;
- ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
- int framenr = ED_space_clip_get_clip_frame_number(sc);
-
- INIT_MINMAX2(min, max);
-
- ED_space_clip_get_size(sc, &width, &height);
-
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track)) {
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
-
- if (marker) {
- float pos[3];
-
- pos[0] = marker->pos[0] + track->offset[0];
- pos[1] = marker->pos[1] + track->offset[1];
- pos[2] = 0.0f;
-
- /* undistortion happens for normalized coords */
- if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
- /* undistortion happens for normalized coords */
- ED_clip_point_undistorted_pos(sc, pos, pos);
- }
-
- pos[0] *= width;
- pos[1] *= height;
-
- mul_v3_m4v3(pos, sc->stabmat, pos);
-
- minmax_v2v2_v2(min, max, pos);
-
- ok = true;
- }
- }
-
- track = track->next;
- }
-
- return ok;
-}
-
-static bool selected_boundbox(const bContext *C, float min[2], float max[2])
-{
- SpaceClip *sc = CTX_wm_space_clip(C);
- if (sc->mode == SC_MODE_TRACKING) {
- return selected_tracking_boundbox(sc, min, max);
- }
-
- if (ED_mask_selected_minmax(C, min, max)) {
- MovieClip *clip = ED_space_clip_get_clip(sc);
- int width, height;
- ED_space_clip_get_size(sc, &width, &height);
- BKE_mask_coord_to_movieclip(clip, &sc->user, min, min);
- BKE_mask_coord_to_movieclip(clip, &sc->user, max, max);
- min[0] *= width;
- min[1] *= height;
- max[0] *= width;
- max[1] *= height;
- return true;
- }
- return false;
-}
-
-bool ED_clip_view_selection(const bContext *C, ARegion *region, bool fit)
-{
- SpaceClip *sc = CTX_wm_space_clip(C);
- int w, h, frame_width, frame_height;
- float min[2], max[2];
-
- ED_space_clip_get_size(sc, &frame_width, &frame_height);
-
- if ((frame_width == 0) || (frame_height == 0) || (sc->clip == NULL)) {
+ float offset_x, offset_y;
+ float zoom;
+ if (!clip_view_calculate_view_selection(C, fit, &offset_x, &offset_y, &zoom)) {
return false;
}
- if (!selected_boundbox(C, min, max)) {
- return false;
- }
-
- /* center view */
- clip_view_center_to_point(
- sc, (max[0] + min[0]) / (2 * frame_width), (max[1] + min[1]) / (2 * frame_height));
-
- w = max[0] - min[0];
- h = max[1] - min[1];
-
- /* set zoom to see all selection */
- if (w > 0 && h > 0) {
- int width, height;
- float zoomx, zoomy, newzoom, aspx, aspy;
-
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
-
- width = BLI_rcti_size_x(&region->winrct) + 1;
- height = BLI_rcti_size_y(&region->winrct) + 1;
-
- zoomx = (float)width / w / aspx;
- zoomy = (float)height / h / aspy;
-
- newzoom = 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy));
-
- if (fit || sc->zoom > newzoom) {
- sc->zoom = newzoom;
- }
- }
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ sc->xof = offset_x;
+ sc->yof = offset_y;
+ sc->zoom = zoom;
return true;
}
@@ -1177,3 +1077,47 @@ void clip_start_prefetch_job(const bContext *C)
/* and finally start the job */
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
+
+void ED_clip_view_lock_state_store(const bContext *C, ClipViewLockState *state)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ BLI_assert(space_clip != NULL);
+
+ state->offset_x = space_clip->xof;
+ state->offset_y = space_clip->yof;
+ state->zoom = space_clip->zoom;
+
+ state->lock_offset_x = 0.0f;
+ state->lock_offset_y = 0.0f;
+
+ if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
+ return;
+ }
+
+ if (!clip_view_calculate_view_selection(
+ C, false, &state->offset_x, &state->offset_y, &state->zoom)) {
+ return;
+ }
+
+ state->lock_offset_x = space_clip->xlockof;
+ state->lock_offset_y = space_clip->ylockof;
+}
+
+void ED_clip_view_lock_state_restore_no_jump(const bContext *C, const ClipViewLockState *state)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ BLI_assert(space_clip != NULL);
+
+ if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
+ return;
+ }
+
+ float offset_x, offset_y;
+ float zoom;
+ if (!clip_view_calculate_view_selection(C, false, &offset_x, &offset_y, &zoom)) {
+ return;
+ }
+
+ space_clip->xlockof = state->offset_x + state->lock_offset_x - offset_x;
+ space_clip->ylockof = state->offset_y + state->lock_offset_y - offset_y;
+}
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 4848ec72f79..202dc00e365 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -171,8 +171,15 @@ void clip_delete_plane_track(struct bContext *C,
struct MovieClip *clip,
struct MovieTrackingPlaneTrack *plane_track);
+void clip_view_offset_for_center_to_point(
+ SpaceClip *sc, const float x, const float y, float *r_offset_x, float *r_offset_y);
void clip_view_center_to_point(SpaceClip *sc, float x, float y);
+bool clip_view_calculate_view_selection(
+ const struct bContext *C, bool fit, float *r_offset_x, float *r_offset_y, float *r_zoom);
+
+bool clip_view_has_locked_selection(const struct bContext *C);
+
void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene);
/* tracking_ops.c */
@@ -191,6 +198,7 @@ void CLIP_OT_clear_solution(struct wmOperatorType *ot);
void CLIP_OT_clear_track_path(struct wmOperatorType *ot);
void CLIP_OT_join_tracks(struct wmOperatorType *ot);
+void CLIP_OT_average_tracks(struct wmOperatorType *ot);
void CLIP_OT_disable_markers(struct wmOperatorType *ot);
void CLIP_OT_hide_tracks(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index cd4a1ffb526..38a05eef6e3 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -125,7 +125,7 @@ static void sclip_zoom_set(const bContext *C,
dx = ((location[0] - 0.5f) * w - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
dy = ((location[1] - 0.5f) * h - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
- if (sc->flag & SC_LOCK_SELECTION) {
+ if (clip_view_has_locked_selection(C)) {
sc->xlockof += dx;
sc->ylockof += dy;
}
@@ -396,7 +396,7 @@ static void view_pan_init(bContext *C, wmOperator *op, const wmEvent *event)
vpd->x = event->x;
vpd->y = event->y;
- if (sc->flag & SC_LOCK_SELECTION) {
+ if (clip_view_has_locked_selection(C)) {
vpd->vec = &sc->xlockof;
}
else {
@@ -434,7 +434,7 @@ static int view_pan_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "offset", offset);
- if (sc->flag & SC_LOCK_SELECTION) {
+ if (clip_view_has_locked_selection(C)) {
sc->xlockof += offset[0];
sc->ylockof += offset[1];
}
@@ -569,7 +569,7 @@ static void view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event)
WM_cursor_modal_set(win, WM_CURSOR_NSEW_SCROLL);
}
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vpd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
vpd->timer_lastdraw = PIL_check_seconds_timer();
@@ -662,7 +662,7 @@ static void view_zoom_apply(
delta = -delta;
}
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
SpaceClip *sclip = CTX_wm_space_clip(C);
double time = PIL_check_seconds_timer();
float time_step = (float)(time - vpd->timer_lastdraw);
@@ -1840,8 +1840,16 @@ void CLIP_OT_cursor_set(wmOperatorType *ot)
static int lock_selection_togglee_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceClip *space_clip = CTX_wm_space_clip(C);
+
+ ClipViewLockState lock_state;
+ ED_clip_view_lock_state_store(C, &lock_state);
+
space_clip->flag ^= SC_LOCK_SELECTION;
+
+ ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CLIP, NULL);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c
index b02f3fe16f6..da9e82043f0 100644
--- a/source/blender/editors/space_clip/clip_toolbar.c
+++ b/source/blender/editors/space_clip/clip_toolbar.c
@@ -23,29 +23,17 @@
#include <string.h>
-#include "DNA_windowmanager_types.h"
-#include "DNA_workspace_types.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "BKE_context.h"
#include "BKE_screen.h"
-#include "RNA_access.h"
-
-#include "WM_api.h"
#include "WM_types.h"
#include "ED_screen.h"
-#include "ED_undo.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
#include "clip_intern.h" /* own include */
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index c7f2a027ba8..bb79eb34129 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -27,10 +27,12 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_rect.h"
#include "BLI_utildefines.h"
#include "BKE_animsys.h"
#include "BKE_context.h"
+#include "BKE_mask.h"
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
@@ -44,6 +46,7 @@
#include "WM_types.h"
#include "ED_clip.h"
+#include "ED_mask.h"
#include "ED_screen.h"
#include "UI_interface.h"
@@ -395,16 +398,232 @@ void clip_delete_plane_track(bContext *C, MovieClip *clip, MovieTrackingPlaneTra
DEG_id_tag_update(&clip->id, 0);
}
-void clip_view_center_to_point(SpaceClip *sc, float x, float y)
+/* Calculate space clip offset to be centered at the given point. */
+void clip_view_offset_for_center_to_point(
+ SpaceClip *sc, const float x, const float y, float *r_offset_x, float *r_offset_y)
{
int width, height;
+ ED_space_clip_get_size(sc, &width, &height);
+
float aspx, aspy;
+ ED_space_clip_get_aspect(sc, &aspx, &aspy);
+
+ *r_offset_x = (x - 0.5f) * width * aspx;
+ *r_offset_y = (y - 0.5f) * height * aspy;
+}
+
+void clip_view_center_to_point(SpaceClip *sc, float x, float y)
+{
+ clip_view_offset_for_center_to_point(sc, x, y, &sc->xof, &sc->yof);
+}
+
+static bool selected_tracking_boundbox(SpaceClip *sc, float min[2], float max[2])
+{
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTrackingTrack *track;
+ int width, height;
+ bool ok = false;
+ ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+
+ INIT_MINMAX2(min, max);
ED_space_clip_get_size(sc, &width, &height);
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
- sc->xof = (x - 0.5f) * width * aspx;
- sc->yof = (y - 0.5f) * height * aspy;
+ track = tracksbase->first;
+ while (track) {
+ if (TRACK_VIEW_SELECTED(sc, track)) {
+ MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+
+ if (marker) {
+ float pos[3];
+
+ pos[0] = marker->pos[0] + track->offset[0];
+ pos[1] = marker->pos[1] + track->offset[1];
+ pos[2] = 0.0f;
+
+ /* undistortion happens for normalized coords */
+ if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
+ /* undistortion happens for normalized coords */
+ ED_clip_point_undistorted_pos(sc, pos, pos);
+ }
+
+ pos[0] *= width;
+ pos[1] *= height;
+
+ mul_v3_m4v3(pos, sc->stabmat, pos);
+
+ minmax_v2v2_v2(min, max, pos);
+
+ ok = true;
+ }
+ }
+
+ track = track->next;
+ }
+
+ return ok;
+}
+
+static bool tracking_has_selection(SpaceClip *space_clip)
+{
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+ const int framenr = ED_space_clip_get_clip_frame_number(space_clip);
+
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
+ if (!TRACK_VIEW_SELECTED(space_clip, track)) {
+ continue;
+ }
+ const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+ if (marker != NULL) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool mask_has_selection(const bContext *C)
+{
+ Mask *mask = CTX_data_edit_mask(C);
+ if (mask == NULL) {
+ return false;
+ }
+
+ LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
+ if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+ LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
+ for (int i = 0; i < spline->tot_point; i++) {
+ const MaskSplinePoint *point = &spline->points[i];
+ const BezTriple *bezt = &point->bezt;
+ if (!MASKPOINT_ISSEL_ANY(point)) {
+ continue;
+ }
+ if (bezt->f2 & SELECT) {
+ return true;
+ }
+
+ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
+ return true;
+ }
+ else {
+ if ((bezt->f1 & SELECT) && (bezt->h1 != HD_VECT)) {
+ return true;
+ }
+ if ((bezt->f3 & SELECT) && (bezt->h2 != HD_VECT)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool selected_boundbox(const bContext *C,
+ float min[2],
+ float max[2],
+ bool handles_as_control_point)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ if (sc->mode == SC_MODE_TRACKING) {
+ return selected_tracking_boundbox(sc, min, max);
+ }
+
+ if (ED_mask_selected_minmax(C, min, max, handles_as_control_point)) {
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ int width, height;
+ ED_space_clip_get_size(sc, &width, &height);
+ BKE_mask_coord_to_movieclip(clip, &sc->user, min, min);
+ BKE_mask_coord_to_movieclip(clip, &sc->user, max, max);
+ min[0] *= width;
+ min[1] *= height;
+ max[0] *= width;
+ max[1] *= height;
+ return true;
+ }
+ return false;
+}
+
+bool clip_view_calculate_view_selection(
+ const bContext *C, bool fit, float *r_offset_x, float *r_offset_y, float *r_zoom)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ int frame_width, frame_height;
+ ED_space_clip_get_size(sc, &frame_width, &frame_height);
+
+ if ((frame_width == 0) || (frame_height == 0) || (sc->clip == NULL)) {
+ return false;
+ }
+
+ /* NOTE: The `fit` argument is set to truth when doing "View to Selected" operator, and it set to
+ * false when this function is used for Lock-to-Selection functionality. When locking to
+ * selection the handles are to use control point position. So we can derive the
+ * `handles_as_control_point` from `fit`.
+ *
+ * TODO(sergey): Make such decision more explicit. Maybe pass use-case for the calculation to
+ * tell operator from lock-to-selection apart. */
+ float min[2], max[2];
+ if (!selected_boundbox(C, min, max, !fit)) {
+ return false;
+ }
+
+ /* center view */
+ clip_view_offset_for_center_to_point(sc,
+ (max[0] + min[0]) / (2 * frame_width),
+ (max[1] + min[1]) / (2 * frame_height),
+ r_offset_x,
+ r_offset_y);
+
+ const int w = max[0] - min[0];
+ const int h = max[1] - min[1];
+
+ /* set zoom to see all selection */
+ *r_zoom = sc->zoom;
+ if (w > 0 && h > 0) {
+ ARegion *region = CTX_wm_region(C);
+
+ int width, height;
+ float zoomx, zoomy, newzoom, aspx, aspy;
+
+ ED_space_clip_get_aspect(sc, &aspx, &aspy);
+
+ width = BLI_rcti_size_x(&region->winrct) + 1;
+ height = BLI_rcti_size_y(&region->winrct) + 1;
+
+ zoomx = (float)width / w / aspx;
+ zoomy = (float)height / h / aspy;
+
+ newzoom = 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy));
+
+ if (fit) {
+ *r_zoom = newzoom;
+ }
+ }
+
+ return true;
+}
+
+/* Returns truth if lock-to-selection is enabled and possible.
+ * Locking to selection is not possible if there is no selection. */
+bool clip_view_has_locked_selection(const bContext *C)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+
+ if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
+ return false;
+ }
+
+ if (space_clip->mode == SC_MODE_TRACKING) {
+ return tracking_has_selection(space_clip);
+ }
+
+ return mask_has_selection(C);
}
void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 3bdf016b64c..2a7c64a83f7 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -47,15 +47,12 @@
#include "ED_clip.h"
#include "ED_mask.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "ED_space_api.h"
#include "ED_time_scrub_ui.h"
-#include "ED_transform.h"
#include "ED_uvedit.h" /* just for ED_image_draw_cursor */
#include "IMB_imbuf.h"
-#include "GPU_framebuffer.h"
#include "GPU_matrix.h"
#include "WM_api.h"
@@ -229,7 +226,7 @@ static void clip_scopes_check_gpencil_change(ScrArea *area)
}
}
-static void clip_area_sync_frame_from_scene(ScrArea *area, Scene *scene)
+static void clip_area_sync_frame_from_scene(ScrArea *area, const Scene *scene)
{
SpaceClip *space_clip = (SpaceClip *)area->spacedata.first;
BKE_movieclip_user_set_frame(&space_clip->user, scene->r.cfra);
@@ -334,8 +331,12 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
return (SpaceLink *)scn;
}
-static void clip_listener(wmWindow *UNUSED(win), ScrArea *area, wmNotifier *wmn, Scene *scene)
+static void clip_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+ const Scene *scene = params->scene;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -514,6 +515,7 @@ static void clip_operatortypes(void)
/* clean-up */
WM_operatortype_append(CLIP_OT_clear_track_path);
WM_operatortype_append(CLIP_OT_join_tracks);
+ WM_operatortype_append(CLIP_OT_average_tracks);
WM_operatortype_append(CLIP_OT_track_copy_color);
WM_operatortype_append(CLIP_OT_clean_tracks);
@@ -988,7 +990,14 @@ static void clip_main_region_draw(const bContext *C, ARegion *region)
}
/* callback */
+ /* TODO(sergey): For being consistent with space image the projection needs to be configured
+ * the way how the commented out code does it. This works correct for tracking data, but it
+ * causes wrong aspect correction for mask editor (see T84990). */
+ // GPU_matrix_push_projection();
+ // wmOrtho2(region->v2d.cur.xmin, region->v2d.cur.xmax, region->v2d.cur.ymin,
+ // region->v2d.cur.ymax);
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
+ // GPU_matrix_pop_projection();
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -1001,12 +1010,11 @@ static void clip_main_region_draw(const bContext *C, ARegion *region)
WM_gizmomap_draw(region->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D);
}
-static void clip_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
@@ -1137,11 +1145,7 @@ static void clip_preview_region_draw(const bContext *C, ARegion *region)
}
}
-static void clip_preview_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void clip_preview_region_listener(const wmRegionListenerParams *UNUSED(params))
{
}
@@ -1182,11 +1186,7 @@ static void clip_channels_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
}
-static void clip_channels_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void clip_channels_region_listener(const wmRegionListenerParams *UNUSED(params))
{
}
@@ -1203,12 +1203,11 @@ static void clip_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void clip_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -1246,12 +1245,11 @@ static void clip_tools_region_draw(const bContext *C, ARegion *region)
/****************** tool properties region ******************/
-static void clip_props_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_props_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -1299,12 +1297,11 @@ static void clip_properties_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void clip_properties_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_properties_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 49313005c43..a903aeed380 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -88,17 +88,16 @@ static int add_marker_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
float pos[2];
+ ClipViewLockState lock_state;
+ ED_clip_view_lock_state_store(C, &lock_state);
+
RNA_float_get_array(op->ptr, "location", pos);
if (!add_marker(C, pos[0], pos[1])) {
return OPERATOR_CANCELLED;
}
- /* Reset offset from locked position, so frame jumping wouldn't be so
- * confusing.
- */
- sc->xlockof = 0;
- sc->ylockof = 0;
+ ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
@@ -244,8 +243,6 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
changed = true;
}
}
- /* Nothing selected now, unlock view so it can be scrolled nice again. */
- sc->flag &= ~SC_LOCK_SELECTION;
if (changed) {
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
}
@@ -314,11 +311,6 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- if (!has_selection) {
- /* Nothing selected now, unlock view so it can be scrolled nice again. */
- sc->flag &= ~SC_LOCK_SELECTION;
- }
-
if (!changed) {
return OPERATOR_CANCELLED;
}
@@ -1225,13 +1217,6 @@ static int hide_tracks_exec(bContext *C, wmOperator *op)
clip->tracking.act_plane_track = NULL;
}
- if (unselected == 0) {
- /* No selection on screen now, unlock view so it can be
- * scrolled nice again.
- */
- sc->flag &= ~SC_LOCK_SELECTION;
- }
-
BKE_tracking_dopesheet_tag_update(tracking);
WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, NULL);
@@ -1490,6 +1475,97 @@ void CLIP_OT_join_tracks(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/********************** Average tracks operator *********************/
+
+static int average_tracks_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ MovieTracking *tracking = &clip->tracking;
+
+ /* Collect source tracks. */
+ int num_source_tracks;
+ MovieTrackingTrack **source_tracks = BKE_tracking_selected_tracks_in_active_object(
+ tracking, &num_source_tracks);
+ if (num_source_tracks == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Create new empty track, which will be the averaged result.
+ * Makes it simple to average all selection to it. */
+ ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
+ MovieTrackingTrack *result_track = BKE_tracking_track_add_empty(tracking, tracks_list);
+
+ /* Perform averaging. */
+ BKE_tracking_tracks_average(result_track, source_tracks, num_source_tracks);
+
+ const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
+ if (!keep_original) {
+ for (int i = 0; i < num_source_tracks; i++) {
+ clip_delete_track(C, clip, source_tracks[i]);
+ }
+ }
+
+ /* Update selection, making the result track active and selected. */
+ /* TODO(sergey): Should become some sort of utility function available for all operators. */
+
+ BKE_tracking_track_select(tracks_list, result_track, TRACK_AREA_ALL, 0);
+ ListBase *plane_tracks_list = BKE_tracking_get_active_plane_tracks(tracking);
+ BKE_tracking_plane_tracks_deselect_all(plane_tracks_list);
+
+ clip->tracking.act_track = result_track;
+ clip->tracking.act_plane_track = NULL;
+
+ /* Inform the dependency graph and interface about changes. */
+ DEG_id_tag_update(&clip->id, 0);
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
+
+ /* Free memory. */
+ MEM_freeN(source_tracks);
+
+ return OPERATOR_FINISHED;
+}
+
+static int average_tracks_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ PropertyRNA *prop_keep_original = RNA_struct_find_property(op->ptr, "keep_original");
+ if (!RNA_property_is_set(op->ptr, prop_keep_original)) {
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ MovieTracking *tracking = &clip->tracking;
+
+ const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
+
+ if (num_selected_tracks == 1) {
+ RNA_property_boolean_set(op->ptr, prop_keep_original, false);
+ }
+ }
+
+ return average_tracks_exec(C, op);
+}
+
+void CLIP_OT_average_tracks(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Average Tracks";
+ ot->description = "Average selected tracks into active";
+ ot->idname = "CLIP_OT_average_tracks";
+
+ /* API callbacks. */
+ ot->exec = average_tracks_exec;
+ ot->invoke = average_tracks_invoke;
+ ot->poll = ED_space_clip_tracking_poll;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties. */
+ PropertyRNA *prop;
+
+ prop = RNA_def_boolean(ot->srna, "keep_original", 1, "Keep Original", "Keep original tracks");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
+
/********************** lock tracks operator *********************/
enum {
diff --git a/source/blender/editors/space_clip/tracking_ops_detect.c b/source/blender/editors/space_clip/tracking_ops_detect.c
index 54ec439471d..86ee94df731 100644
--- a/source/blender/editors/space_clip/tracking_ops_detect.c
+++ b/source/blender/editors/space_clip/tracking_ops_detect.c
@@ -21,14 +21,10 @@
* \ingroup spclip
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_gpencil_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "BLI_utildefines.h"
-
#include "BKE_context.h"
#include "BKE_movieclip.h"
#include "BKE_report.h"
diff --git a/source/blender/editors/space_clip/tracking_ops_stabilize.c b/source/blender/editors/space_clip/tracking_ops_stabilize.c
index 5e43b7c7ec6..d0b4d18c6d9 100644
--- a/source/blender/editors/space_clip/tracking_ops_stabilize.c
+++ b/source/blender/editors/space_clip/tracking_ops_stabilize.c
@@ -21,8 +21,6 @@
* \ingroup spclip
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
diff --git a/source/blender/editors/space_clip/tracking_ops_track.c b/source/blender/editors/space_clip/tracking_ops_track.c
index 585b13b426e..e480ec2db05 100644
--- a/source/blender/editors/space_clip/tracking_ops_track.c
+++ b/source/blender/editors/space_clip/tracking_ops_track.c
@@ -30,7 +30,6 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_movieclip.h"
-#include "BKE_report.h"
#include "BKE_tracking.h"
#include "WM_api.h"
diff --git a/source/blender/editors/space_clip/tracking_ops_utils.c b/source/blender/editors/space_clip/tracking_ops_utils.c
index 1f959e94309..0f6bd6e039a 100644
--- a/source/blender/editors/space_clip/tracking_ops_utils.c
+++ b/source/blender/editors/space_clip/tracking_ops_utils.c
@@ -21,12 +21,8 @@
* \ingroup spclip
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_space_types.h"
-#include "BLI_utildefines.h"
-
#include "BKE_context.h"
#include "BKE_tracking.h"
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 063ea9592aa..558c0bec11d 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -304,6 +304,9 @@ static int mouse_select(bContext *C, const float co[2], const bool extend, const
track = find_nearest_track(sc, tracksbase, co, &distance_to_track);
plane_track = find_nearest_plane_track(sc, plane_tracks_base, co, &distance_to_plane_track);
+ ClipViewLockState lock_state;
+ ED_clip_view_lock_state_store(C, &lock_state);
+
/* Do not select beyond some reasonable distance, that is useless and
* prevents the 'deselect on nothing' behavior. */
if (distance_to_track > 0.05f) {
@@ -377,10 +380,7 @@ static int mouse_select(bContext *C, const float co[2], const bool extend, const
ED_mask_deselect_all(C);
}
- if (!extend) {
- sc->xlockof = 0.0f;
- sc->ylockof = 0.0f;
- }
+ ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
BKE_tracking_dopesheet_tag_update(tracking);
@@ -867,14 +867,16 @@ static int select_all_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
- int action = RNA_enum_get(op->ptr, "action");
+ const int action = RNA_enum_get(op->ptr, "action");
- bool has_selection = false;
+ ClipViewLockState lock_state;
+ ED_clip_view_lock_state_store(C, &lock_state);
+ bool has_selection = false;
ED_clip_select_all(sc, action, &has_selection);
- if (!has_selection) {
- sc->flag &= ~SC_LOCK_SELECTION;
+ if (has_selection) {
+ ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
}
BKE_tracking_dopesheet_tag_update(tracking);
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 77f1111624d..05595e0b393 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -18,7 +18,7 @@
* \ingroup spconsole
*/
-#include <ctype.h> /* ispunct */
+#include <ctype.h> /* #ispunct */
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -749,7 +749,7 @@ static int console_clear_exec(bContext *C, wmOperator *op)
/*ConsoleLine *ci = */ console_history_verify(C);
- if (scrollback) { /* last item in mistory */
+ if (scrollback) { /* Last item in history. */
while (sc->scrollback.first) {
console_scrollback_free(sc, sc->scrollback.first);
}
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 9b8e9e0e871..b24579d9871 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -41,7 +41,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_framebuffer.h"
#include "console_intern.h" /* own include */
/* ******************** default callbacks for console space ***************** */
@@ -216,7 +215,7 @@ static void console_main_region_draw(const bContext *C, ARegion *region)
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
- /* worlks best with no view2d matrix set */
+ /* Works best with no view2d matrix set. */
UI_view2d_view_ortho(v2d);
/* data... */
@@ -273,13 +272,11 @@ static void console_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void console_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void console_main_region_listener(const wmRegionListenerParams *params)
{
- // SpaceInfo *sinfo = area->spacedata.first;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 8e9093151ba..c1dcf2e56d3 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -131,7 +131,15 @@ static void draw_tile(int sx, int sy, int width, int height, int colorid, int sh
UI_GetThemeColorShade4fv(colorid, shade, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(
- true, (float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f, color);
+ &(const rctf){
+ .xmin = (float)sx,
+ .xmax = (float)(sx + width),
+ .ymin = (float)(sy - height),
+ .ymax = (float)sy,
+ },
+ true,
+ 5.0f,
+ color);
}
static void file_draw_icon(uiBlock *block,
@@ -465,7 +473,7 @@ static void file_draw_preview(uiBlock *block,
but = uiDefBut(block, UI_BTYPE_LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, NULL);
- /* dragregion */
+ /* Drag-region. */
if (drag) {
ID *id;
@@ -546,7 +554,7 @@ static void draw_background(FileLayout *layout, View2D *v2d)
for (i = 2; (i <= layout->rows + 1); i += 2) {
sy = (int)v2d->cur.ymax - layout->offset_top - i * item_height - layout->tile_border_y;
- /* Offsett pattern slightly to add scroll effect. */
+ /* Offset pattern slightly to add scroll effect. */
sy += round_fl_to_int(item_height * (v2d->tot.ymax - v2d->cur.ymax) / item_height);
immRectf(pos,
diff --git a/source/blender/editors/space_file/file_utils.c b/source/blender/editors/space_file/file_utils.c
index 9d85996c559..186bc04fafe 100644
--- a/source/blender/editors/space_file/file_utils.c
+++ b/source/blender/editors/space_file/file_utils.c
@@ -19,7 +19,6 @@
*/
#include "BLI_fileops.h"
-#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index d66219c7549..33c37875372 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -276,6 +276,7 @@ typedef struct FileListInternEntry {
char *redirection_path;
/** not strictly needed, but used during sorting, avoids to have to recompute it there... */
char *name;
+ bool free_name;
/**
* This is data from the current main, represented by this file. It's crucial that this is
@@ -1366,7 +1367,7 @@ static bool filelist_checkdir_main_assets(struct FileList *UNUSED(filelist),
static void filelist_entry_clear(FileDirEntry *entry)
{
- if (entry->name) {
+ if (entry->name && ((entry->flags & FILE_ENTRY_NAME_FREE) != 0)) {
MEM_freeN(entry->name);
}
if (entry->description) {
@@ -1451,7 +1452,7 @@ static void filelist_intern_entry_free(FileListInternEntry *entry)
if (entry->redirection_path) {
MEM_freeN(entry->redirection_path);
}
- if (entry->name) {
+ 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. */
@@ -1953,7 +1954,13 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
ret->entry = rev;
ret->relpath = BLI_strdup(entry->relpath);
- ret->name = BLI_strdup(entry->name);
+ if (entry->free_name) {
+ ret->name = BLI_strdup(entry->name);
+ ret->flags |= FILE_ENTRY_NAME_FREE;
+ }
+ else {
+ ret->name = entry->name;
+ }
ret->description = BLI_strdupcat(filelist->filelist.root, entry->relpath);
memcpy(ret->uuid, entry->uuid, sizeof(ret->uuid));
ret->blentype = entry->blentype;
@@ -3175,6 +3182,7 @@ static void filelist_readjob_do(const bool do_lib,
entry->relpath = BLI_strdup(dir + 2); /* + 2 to remove '//'
* added by BLI_path_rel to rel_subdir. */
entry->name = BLI_strdup(fileentry_uiname(root, entry->relpath, entry->typeflag, dir));
+ entry->free_name = true;
/* Here we decide whether current filedirentry is to be listed too, or not. */
if (max_recursion && (is_lib || (recursion_level <= max_recursion))) {
@@ -3288,7 +3296,8 @@ static void filelist_readjob_main_assets(Main *current_main,
entry = MEM_callocN(sizeof(*entry), __func__);
entry->relpath = BLI_strdup(id_code_name);
- entry->name = BLI_strdup(id_iter->name + 2);
+ entry->name = id_iter->name + 2;
+ entry->free_name = false;
entry->typeflag |= FILE_TYPE_BLENDERLIB | FILE_TYPE_ASSET;
entry->blentype = GS(id_iter->name);
*((uint32_t *)entry->uuid) = atomic_add_and_fetch_uint32(
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 6b74b344375..6e5791cad52 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -460,7 +460,7 @@ bool ED_fileselect_is_asset_browser(const SpaceFile *sfile)
void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool *is_maximized)
{
- /* Get DPI/pixelsize independent size to be stored in preferences. */
+ /* Get DPI/pixel-size independent size to be stored in preferences. */
WM_window_set_dpi(win); /* Ensure the DPI is taken from the right window. */
win_size[0] = WM_window_pixels_x(win) / UI_DPI_FAC;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 7f33b0212d6..178ca264182 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -104,6 +104,7 @@ static ARegion *file_tool_props_region_ensure(ScrArea *area, ARegion *region_pre
BLI_insertlinkafter(&area->regionbase, region_prev, region);
region->regiontype = RGN_TYPE_TOOL_PROPS;
region->alignment = RGN_ALIGN_RIGHT;
+ region->flag = RGN_FLAG_HIDDEN;
return region;
}
@@ -246,13 +247,13 @@ static void file_ensure_valid_region_state(bContext *C,
BLI_assert(region_tools);
if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) {
- ARegion *region_execute = file_execute_region_ensure(area, region_tools);
- ARegion *region_props = file_tool_props_region_ensure(area, region_execute);
-
- /* Hide specific regions by default. */
- region_props->flag |= RGN_FLAG_HIDDEN;
- region_execute->flag |= RGN_FLAG_HIDDEN;
+ file_tool_props_region_ensure(area, region_tools);
+ ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE);
+ if (region_execute) {
+ ED_region_remove(C, area, region_execute);
+ needs_init = true;
+ }
ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI);
if (region_ui) {
ED_region_remove(C, area, region_ui);
@@ -260,7 +261,7 @@ static void file_ensure_valid_region_state(bContext *C,
}
}
/* If there's an file-operation, ensure we have the option and execute region */
- else if (sfile->op) {
+ else if (sfile->op && !BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS)) {
ARegion *region_ui = file_ui_region_ensure(area, region_tools);
ARegion *region_execute = file_execute_region_ensure(area, region_ui);
ARegion *region_props = file_tool_props_region_ensure(area, region_execute);
@@ -275,17 +276,18 @@ static void file_ensure_valid_region_state(bContext *C,
needs_init = true;
}
/* If there's _no_ file-operation, ensure we _don't_ have the option and execute region */
- else {
+ else if (!sfile->op) {
ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS);
ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE);
ARegion *region_ui = file_ui_region_ensure(area, region_tools);
UNUSED_VARS(region_ui);
+ if (region_execute) {
+ ED_region_remove(C, area, region_execute);
+ needs_init = true;
+ }
if (region_props) {
- BLI_assert(region_execute);
-
ED_region_remove(C, area, region_props);
- ED_region_remove(C, area, region_execute);
needs_init = true;
}
}
@@ -390,11 +392,10 @@ static void file_refresh(const bContext *C, ScrArea *area)
ED_area_tag_redraw(area);
}
-static void file_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void file_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceFile *sfile = (SpaceFile *)area->spacedata.first;
/* context changes */
@@ -445,12 +446,11 @@ static void file_main_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
}
-static void file_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void file_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SPACE:
@@ -463,19 +463,24 @@ static void file_main_region_listener(wmWindow *UNUSED(win),
break;
}
break;
+ case NC_ID:
+ if (ELEM(wmn->action, NA_RENAME)) {
+ /* In case the filelist shows ID names. */
+ ED_region_tag_redraw(region);
+ }
+ break;
}
}
-static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void file_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceFile *sfile = area->spacedata.first;
- FileSelectParams *params = ED_fileselect_ensure_active_params(sfile);
+
+ FileSelectParams *file_params = ED_fileselect_ensure_active_params(sfile);
/* This is a bit odd that a region owns the subscriber for an area,
* keep for now since all subscribers for WM are regions.
* May be worth re-visiting later. */
@@ -497,7 +502,7 @@ static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
/* FileSelectParams */
{
PointerRNA ptr;
- RNA_pointer_create(&screen->id, &RNA_FileSelectParams, params, &ptr);
+ RNA_pointer_create(&screen->id, &RNA_FileSelectParams, file_params, &ptr);
/* All properties for this space type. */
WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_area_tag_refresh, __func__);
@@ -647,18 +652,23 @@ static void file_tools_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void file_tools_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void file_tools_region_listener(const wmRegionListenerParams *UNUSED(params))
{
-#if 0
- /* context changes */
+}
+
+static void file_tool_props_region_listener(const wmRegionListenerParams *params)
+{
+ const wmNotifier *wmn = params->notifier;
+ ARegion *region = params->region;
+
switch (wmn->category) {
- /* pass */
+ case NC_ID:
+ if (ELEM(wmn->action, NA_RENAME)) {
+ /* In case the filelist shows ID names. */
+ ED_region_tag_redraw(region);
+ }
+ break;
}
-#endif
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -715,12 +725,11 @@ static void file_execution_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void file_ui_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void file_ui_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SPACE:
@@ -928,7 +937,7 @@ void ED_spacetype_file(void)
art->prefsizex = 240;
art->prefsizey = 60;
art->keymapflag = ED_KEYMAP_UI;
- art->listener = file_tools_region_listener;
+ art->listener = file_tool_props_region_listener;
art->init = file_tools_region_init;
art->draw = file_tools_region_draw;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index fac38ef7b91..31f606e515d 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -178,7 +178,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
x = (float)CFRA;
}
- /* Normalise units of cursor's value. */
+ /* Normalize units of cursor's value. */
if (sipo) {
y = (sipo->cursorVal / unit_scale) - offset;
}
@@ -2263,7 +2263,7 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- /* Normalise cursor value (for normalised F-Curves display). */
+ /* Normalize cursor value (for normalized F-Curves display). */
if (mode == GRAPHKEYS_SNAP_VALUE) {
short mapping_flag = ANIM_get_normalization_flags(ac);
float offset;
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 63acc2a1774..32396a70cce 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -32,15 +32,11 @@
#include "BKE_context.h"
#include "BKE_global.h"
-#include "BKE_main.h"
#include "UI_view2d.h"
#include "ED_anim_api.h"
-#include "ED_markers.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "ED_transform.h"
#include "graph_intern.h"
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index 4cda6b34a01..3e52dc7377b 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -380,7 +380,7 @@ static int graphkeys_decimate_modal(bContext *C, wmOperator *op, const wmEvent *
break;
}
- /* Unhandled event - maybe it was some view manip? */
+ /* Unhandled event - maybe it was some view manipulation? */
/* Allow to pass through. */
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
}
@@ -505,15 +505,15 @@ void GRAPH_OT_decimate(wmOperatorType *ot)
"Mode",
"Which mode to use for decimation");
- RNA_def_float_percentage(ot->srna,
- "remove_ratio",
- 1.0f / 3.0f,
- 0.0f,
- 1.0f,
- "Remove",
- "The percentage of keyframes to remove",
- 0.0f,
- 1.0f);
+ RNA_def_float_factor(ot->srna,
+ "remove_ratio",
+ 1.0f / 3.0f,
+ 0.0f,
+ 1.0f,
+ "Remove",
+ "The ratio of remaining keyframes after the operation",
+ 0.0f,
+ 1.0f);
RNA_def_float(ot->srna,
"remove_error_margin",
0.0f,
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index 8463c21b1ad..c37d9f42c12 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -38,8 +38,6 @@
#include "BKE_fcurve.h"
#include "BKE_screen.h"
-#include "WM_api.h"
-
#include "ED_anim_api.h"
#include "ED_screen.h"
#include "UI_interface.h"
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 791039498e8..9f01773eadf 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -403,12 +403,11 @@ static void graph_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void graph_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void graph_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -470,14 +469,14 @@ static void graph_region_listener(wmWindow *UNUSED(win),
}
}
-static void graph_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void graph_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceGraphEditor, area->spacedata.first, &ptr);
@@ -546,11 +545,10 @@ static void graph_region_message_subscribe(const struct bContext *UNUSED(C),
}
/* editor level listener */
-static void graph_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void graph_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceGraph *sipo = (SpaceGraph *)area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 63e5ae64a8c..67d5055ec65 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -466,7 +466,7 @@ static void sima_draw_zbuf_pixels(
{
const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
- /* Slowwww */
+ /* Very slow! */
float *rectf = MEM_mallocN(rectx * recty * sizeof(float), "temp");
for (int a = rectx * recty - 1; a >= 0; a--) {
/* zbuffer values are signed, so we need to shift color range */
@@ -874,7 +874,7 @@ void draw_image_main(const bContext *C, ARegion *region)
if (show_stereo3d) {
if (show_multilayer) {
- /* update multiindex and pass for the current eye */
+ /* Update multi-index and pass for the current eye. */
BKE_image_multilayer_index(ima->rr, &sima->iuser);
}
else {
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index 100556ad29a..0044c6072a4 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -71,6 +71,7 @@ void IMAGE_OT_save_all_modified(struct wmOperatorType *ot);
void IMAGE_OT_pack(struct wmOperatorType *ot);
void IMAGE_OT_unpack(struct wmOperatorType *ot);
+void IMAGE_OT_flip(struct wmOperatorType *ot);
void IMAGE_OT_invert(struct wmOperatorType *ot);
void IMAGE_OT_resize(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 86e52814d6f..4008ca228ac 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -36,9 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_fileops.h"
-#include "BLI_fileops_types.h"
#include "BLI_ghash.h"
-#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -48,7 +46,6 @@
#include "DNA_camera_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -62,14 +59,10 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_packedFile.h"
-#include "BKE_paint.h"
#include "BKE_report.h"
-#include "BKE_scene.h"
-#include "BKE_screen.h"
#include "DEG_depsgraph.h"
-#include "GPU_immediate.h"
#include "GPU_state.h"
#include "IMB_colormanagement.h"
@@ -467,7 +460,7 @@ static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *eve
UI_view2d_region_to_view(
&region->v2d, event->mval[0], event->mval[1], &vpd->location[0], &vpd->location[1]);
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vpd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
vpd->timer_lastdraw = PIL_check_seconds_timer();
@@ -579,12 +572,10 @@ static void image_zoom_apply(ViewZoomData *vpd,
delta = -delta;
}
- if (viewzoom == USER_ZOOM_CONT) {
+ if (viewzoom == USER_ZOOM_CONTINUE) {
double time = PIL_check_seconds_timer();
float time_step = (float)(time - vpd->timer_lastdraw);
float zfac;
-
- /* oldstyle zoom */
zfac = 1.0f + ((delta / 20.0f) * time_step);
vpd->timer_lastdraw = time;
/* this is the final zoom, but instead make it into a factor */
@@ -900,7 +891,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
}
}
else if (ED_space_image_check_show_maskedit(sima, obedit)) {
- if (!ED_mask_selected_minmax(C, min, max)) {
+ if (!ED_mask_selected_minmax(C, min, max, false)) {
return OPERATOR_CANCELLED;
}
}
@@ -2663,6 +2654,126 @@ void IMAGE_OT_new(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Flip Operator
+ * \{ */
+
+static int image_flip_exec(bContext *C, wmOperator *op)
+{
+ Image *ima = image_from_context(C);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ SpaceImage *sima = CTX_wm_space_image(C);
+ const bool is_paint = ((sima != NULL) && (sima->mode == SI_MODE_PAINT));
+
+ if (ibuf == NULL) {
+ /* TODO: this should actually never happen, but does for render-results -> cleanup. */
+ return OPERATOR_CANCELLED;
+ }
+
+ const bool flip_horizontal = RNA_boolean_get(op->ptr, "use_flip_horizontal");
+ const bool flip_vertical = RNA_boolean_get(op->ptr, "use_flip_vertical");
+
+ if (!flip_horizontal && !flip_vertical) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return OPERATOR_FINISHED;
+ }
+
+ ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, &sima->iuser);
+
+ if (is_paint) {
+ ED_imapaint_clear_partial_redraw();
+ }
+
+ const int size_x = ibuf->x;
+ const int size_y = ibuf->y;
+
+ if (ibuf->rect_float) {
+ float *float_pixels = (float *)ibuf->rect_float;
+
+ float *orig_float_pixels = MEM_dupallocN(float_pixels);
+ for (int x = 0; x < size_x; x++) {
+ for (int y = 0; y < size_y; y++) {
+ const int source_pixel_x = flip_horizontal ? size_x - x - 1 : x;
+ const int source_pixel_y = flip_vertical ? size_y - y - 1 : y;
+
+ float *source_pixel = &orig_float_pixels[4 * (source_pixel_x + source_pixel_y * size_x)];
+ float *target_pixel = &float_pixels[4 * (x + y * size_x)];
+
+ copy_v4_v4(target_pixel, source_pixel);
+ }
+ }
+ MEM_freeN(orig_float_pixels);
+
+ if (ibuf->rect) {
+ IMB_rect_from_float(ibuf);
+ }
+ }
+ else if (ibuf->rect) {
+ char *char_pixels = (char *)ibuf->rect;
+ char *orig_char_pixels = MEM_dupallocN(char_pixels);
+ for (int x = 0; x < size_x; x++) {
+ for (int y = 0; y < size_y; y++) {
+ const int source_pixel_x = flip_horizontal ? size_x - x - 1 : x;
+ const int source_pixel_y = flip_vertical ? size_y - y - 1 : y;
+
+ char *source_pixel = &orig_char_pixels[4 * (source_pixel_x + source_pixel_y * size_x)];
+ char *target_pixel = &char_pixels[4 * (x + y * size_x)];
+
+ copy_v4_v4_char(target_pixel, source_pixel);
+ }
+ }
+ MEM_freeN(orig_char_pixels);
+ }
+ else {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return OPERATOR_CANCELLED;
+ }
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ BKE_image_mark_dirty(ima, ibuf);
+
+ if (ibuf->mipmap[0]) {
+ ibuf->userflags |= IB_MIPMAP_INVALID;
+ }
+
+ ED_image_undo_push_end();
+
+ /* force GPU re-upload, all image is invalid. */
+ BKE_image_free_gputextures(ima);
+
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void IMAGE_OT_flip(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Flip Image";
+ ot->idname = "IMAGE_OT_flip";
+ ot->description = "Flip the image";
+
+ /* api callbacks */
+ ot->exec = image_flip_exec;
+ ot->poll = image_from_context_has_data_poll_no_image_user;
+
+ /* properties */
+ PropertyRNA *prop;
+ prop = RNA_def_boolean(
+ ot->srna, "use_flip_horizontal", false, "Horizontal", "Flip the image horizontally");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna, "use_flip_vertical", false, "Vertical", "Flip the image vertically");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Invert Operators
* \{ */
@@ -2747,7 +2858,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
- /* force GPU reupload, all image is invalid */
+ /* Force GPU re-upload, all image is invalid. */
BKE_image_free_gputextures(ima);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -2838,7 +2949,7 @@ static int image_scale_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
- /* force GPU reupload, all image is invalid */
+ /* Force GPU re-upload, all image is invalid. */
BKE_image_free_gputextures(ima);
DEG_id_tag_update(&ima->id, 0);
diff --git a/source/blender/editors/space_image/image_sequence.c b/source/blender/editors/space_image/image_sequence.c
index 81f2ced7dee..02546e3e3b3 100644
--- a/source/blender/editors/space_image/image_sequence.c
+++ b/source/blender/editors/space_image/image_sequence.c
@@ -27,7 +27,6 @@
#include "BLI_fileops.h"
#include "BLI_fileops_types.h"
-#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_path_util.h"
@@ -35,7 +34,6 @@
#include "BLI_utildefines.h"
#include "DNA_image_types.h"
-#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
#include "RNA_access.h"
@@ -45,8 +43,6 @@
#include "ED_image.h"
-#include "WM_types.h"
-
typedef struct ImageFrame {
struct ImageFrame *next, *prev;
int framenr;
diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
index 1d5725033e0..391c68f4231 100644
--- a/source/blender/editors/space_image/image_undo.c
+++ b/source/blender/editors/space_image/image_undo.c
@@ -947,13 +947,15 @@ static void image_undosys_step_decode_redo(ImageUndoStep *us)
}
static void image_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir, bool is_final)
+ struct bContext *C, struct Main *bmain, UndoStep *us_p, const eUndoStepDir dir, bool is_final)
{
+ BLI_assert(dir != STEP_INVALID);
+
ImageUndoStep *us = (ImageUndoStep *)us_p;
- if (dir < 0) {
+ if (dir == STEP_UNDO) {
image_undosys_step_decode_undo(us, is_final);
}
- else {
+ else if (dir == STEP_REDO) {
image_undosys_step_decode_redo(us);
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 186f2d3a5a8..69976bc088c 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -24,8 +24,6 @@
#include "DNA_gpencil_types.h"
#include "DNA_image_types.h"
#include "DNA_mask_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -37,14 +35,9 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_editmesh.h"
#include "BKE_image.h"
-#include "BKE_layer.h"
#include "BKE_lib_id.h"
-#include "BKE_material.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_workspace.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -56,7 +49,6 @@
#include "ED_image.h"
#include "ED_mask.h"
-#include "ED_mesh.h"
#include "ED_node.h"
#include "ED_render.h"
#include "ED_screen.h"
@@ -65,19 +57,13 @@
#include "ED_uvedit.h"
#include "WM_api.h"
-#include "WM_message.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_batch_presets.h"
-#include "GPU_framebuffer.h"
-#include "GPU_viewport.h"
-
#include "DRW_engine.h"
-#include "DRW_engine_types.h"
#include "image_intern.h"
@@ -234,6 +220,7 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_pack);
WM_operatortype_append(IMAGE_OT_unpack);
+ WM_operatortype_append(IMAGE_OT_flip);
WM_operatortype_append(IMAGE_OT_invert);
WM_operatortype_append(IMAGE_OT_resize);
@@ -320,8 +307,11 @@ static void image_refresh(const bContext *C, ScrArea *area)
}
}
-static void image_listener(wmWindow *win, ScrArea *area, wmNotifier *wmn, Scene *UNUSED(scene))
+static void image_listener(const wmSpaceTypeListenerParams *params)
{
+ wmWindow *win = params->window;
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceImage *sima = (SpaceImage *)area->spacedata.first;
/* context changes */
@@ -728,12 +718,12 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
draw_image_cache(C, region);
}
-static void image_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_main_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GEOM:
@@ -843,12 +833,11 @@ static void image_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels_draw(C, region);
}
-static void image_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_TEXTURE:
@@ -906,12 +895,11 @@ static void image_tools_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void image_tools_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_tools_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
@@ -963,12 +951,11 @@ static void image_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void image_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 414bce29502..be3b60d581b 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -35,7 +35,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_framebuffer.h"
#include "info_intern.h"
#include "textview.h"
@@ -56,47 +55,11 @@ static enum eTextViewContext_LineFlag report_line_data(TextViewContext *tvc,
int shade = (tvc->iter_tmp % 2) ? 4 : -4;
UI_GetThemeColorShade4ubv(bg_id, shade, bg);
- /* Icon color and backgound depend of report type. */
+ /* Don't show icon on subsequent rows of multi-row report. */
+ *r_icon = (tvc->iter_char_begin != 0) ? ICON_NONE : UI_icon_from_report_type(report->type);
- int icon_fg_id;
- int icon_bg_id;
-
- if (tvc->iter_char_begin != 0) {
- *r_icon = ICON_NONE;
- }
- else if (report->type & RPT_ERROR_ALL) {
- icon_fg_id = TH_INFO_ERROR_TEXT;
- icon_bg_id = TH_INFO_ERROR;
- *r_icon = ICON_CANCEL;
- }
- else if (report->type & RPT_WARNING_ALL) {
- icon_fg_id = TH_INFO_WARNING_TEXT;
- icon_bg_id = TH_INFO_WARNING;
- *r_icon = ICON_ERROR;
- }
- else if (report->type & RPT_INFO_ALL) {
- icon_fg_id = TH_INFO_INFO_TEXT;
- icon_bg_id = TH_INFO_INFO;
- *r_icon = ICON_INFO;
- }
- else if (report->type & RPT_DEBUG_ALL) {
- icon_fg_id = TH_INFO_DEBUG_TEXT;
- icon_bg_id = TH_INFO_DEBUG;
- *r_icon = ICON_SYSTEM;
- }
- else if (report->type & RPT_PROPERTY) {
- icon_fg_id = TH_INFO_PROPERTY_TEXT;
- icon_bg_id = TH_INFO_PROPERTY;
- *r_icon = ICON_OPTIONS;
- }
- else if (report->type & RPT_OPERATOR) {
- icon_fg_id = TH_INFO_OPERATOR_TEXT;
- icon_bg_id = TH_INFO_OPERATOR;
- *r_icon = ICON_CHECKMARK;
- }
- else {
- *r_icon = ICON_NONE;
- }
+ int icon_fg_id = UI_text_colorid_from_report_type(report->type);
+ int icon_bg_id = UI_icon_colorid_from_report_type(report->type);
if (report->flag & SELECT) {
icon_fg_id = TH_INFO_SELECTED;
@@ -105,6 +68,8 @@ static enum eTextViewContext_LineFlag report_line_data(TextViewContext *tvc,
if (*r_icon != ICON_NONE) {
UI_GetThemeColor4ubv(icon_fg_id, r_icon_fg);
+ /* This theme color is RGB only, so set alpha. */
+ r_icon_fg[3] = 255;
UI_GetThemeColor4ubv(icon_bg_id, r_icon_bg);
return TVC_LINE_FG | TVC_LINE_BG | TVC_LINE_ICON | TVC_LINE_ICON_FG | TVC_LINE_ICON_BG;
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 3bd23eab836..0583628be43 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -24,7 +24,6 @@
#include <stdio.h>
#include <string.h>
-#include "DNA_packedFile_types.h"
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
@@ -52,8 +51,6 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "IMB_imbuf_types.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
@@ -567,15 +564,7 @@ static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), co
}
/* set target color based on report type */
- if (report->type & RPT_ERROR_ALL) {
- UI_GetThemeColorType3fv(TH_INFO_ERROR, SPACE_INFO, target_col);
- }
- else if (report->type & RPT_WARNING_ALL) {
- UI_GetThemeColorType3fv(TH_INFO_WARNING, SPACE_INFO, target_col);
- }
- else if (report->type & RPT_INFO_ALL) {
- UI_GetThemeColorType3fv(TH_INFO_INFO, SPACE_INFO, target_col);
- }
+ UI_GetThemeColorType3fv(UI_icon_colorid_from_report_type(report->type), SPACE_INFO, target_col);
target_col[3] = 0.65f;
if (rti->widthfac == 0.0f) {
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 8d3f21aefeb..dfc0abee704 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -29,8 +29,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -43,12 +41,9 @@
#include "RNA_access.h"
-#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "BLO_readfile.h"
-#include "GPU_framebuffer.h"
#include "info_intern.h" /* own include */
/* ******************** default callbacks for info space ***************** */
@@ -150,7 +145,7 @@ static void info_main_region_draw(const bContext *C, ARegion *region)
info_textview_update_rect(C, region);
- /* worlks best with no view2d matrix set */
+ /* Works best with no view2d matrix set. */
UI_view2d_view_ortho(v2d);
info_textview_main(sinfo, region, CTX_wm_reports(C));
@@ -204,13 +199,10 @@ static void info_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void info_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void info_main_region_listener(const wmRegionListenerParams *params)
{
- // SpaceInfo *sinfo = area->spacedata.first;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
/* context changes */
switch (wmn->category) {
@@ -223,12 +215,11 @@ static void info_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void info_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void info_header_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -259,14 +250,11 @@ static void info_header_listener(wmWindow *UNUSED(win),
}
}
-static void info_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void info_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index a489216afd1..aef59e89325 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -225,13 +225,16 @@ static bool textview_draw_string(TextViewDrawState *tds,
rgba_uchar_to_float(col, icon_bg);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- hpadding,
- line_top - bg_size - vpadding,
- bg_size + hpadding,
- line_top - vpadding,
- 4 * UI_DPI_FAC,
- col);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = hpadding,
+ .xmax = bg_size + hpadding,
+ .ymin = line_top - bg_size - vpadding,
+ .ymax = line_top - vpadding,
+ },
+ true,
+ 4 * UI_DPI_FAC,
+ col);
}
if (icon) {
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 6fe980cf657..eea81e425c2 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -493,7 +493,18 @@ static void nla_draw_strip(SpaceNla *snla,
/* strip is in normal track */
UI_draw_roundbox_corner_set(UI_CNR_ALL); /* all corners rounded */
- UI_draw_roundbox_shade_x(true, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1, color);
+ UI_draw_roundbox_shade_x(
+ &(const rctf){
+ .xmin = strip->start,
+ .xmax = strip->end,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ true,
+ 0.0,
+ 0.5,
+ 0.1,
+ color);
/* restore current vertex format & program (roundbox trashes it) */
shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -547,7 +558,18 @@ static void nla_draw_strip(SpaceNla *snla,
}
else {
/* non-muted - draw solid, rounded outline */
- UI_draw_roundbox_shade_x(false, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1, color);
+ UI_draw_roundbox_shade_x(
+ &(const rctf){
+ .xmin = strip->start,
+ .xmax = strip->end,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ false,
+ 0.0,
+ 0.0,
+ 0.1,
+ color);
/* restore current vertex format & program (roundbox trashes it) */
shdr_pos = nla_draw_use_dashed_outlines(color, muted);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index d7bf6c324ac..893d2c0e2c8 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -62,7 +62,6 @@
#include "DEG_depsgraph_build.h"
#include "UI_interface.h"
-#include "UI_resources.h"
#include "UI_view2d.h"
#include "nla_intern.h" /* own include */
@@ -215,7 +214,7 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
return false;
}
- /* for each AnimData block with NLA-data, try exitting tweak-mode */
+ /* For each AnimData block with NLA-data, try exiting tweak-mode. */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->data;
@@ -418,7 +417,7 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa
int filter;
SpaceNla *snla = (SpaceNla *)ac->sl;
- /* NOTE: not bool, since we want prioritise individual channels over expanders */
+ /* NOTE: not bool, since we want prioritize individual channels over expanders. */
short found = 0;
/* get all items - we need to do it this way */
@@ -442,7 +441,7 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa
found = acf->channel_role;
/* only stop our search when we've found an actual channel
- * - datablock expanders get less priority so that we don't abort prematurely
+ * - data-block expanders get less priority so that we don't abort prematurely
*/
if (found == ACHANNEL_ROLE_CHANNEL) {
break;
@@ -1532,11 +1531,11 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
- /* No re-ordering of strips whithin non-local tracks of override data. */
+ /* No re-ordering of strips within non-local tracks of override data. */
continue;
}
- /* make temporary metastrips so that entire islands of selections can be moved around */
+ /* Make temporary meta-strips so that entire islands of selections can be moved around. */
BKE_nlastrips_make_metas(&nlt->strips, 1);
/* special case: if there is only 1 island
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 2e32c496170..631dc2e550c 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -30,16 +30,11 @@
#include "BKE_screen.h"
#include "ED_anim_api.h"
-#include "ED_markers.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
-#include "ED_transform.h"
#include "WM_api.h"
#include "WM_types.h"
-#include "RNA_access.h"
-
#include "nla_intern.h" /* own include */
/* ************************** poll callbacks for operators **********************************/
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index c6fe1b8539e..011cd7e2651 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -24,7 +24,6 @@
#include <stdio.h>
#include <string.h>
-#include "DNA_anim_types.h"
#include "DNA_collection_types.h"
#include "DNA_scene_types.h"
@@ -52,7 +51,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_framebuffer.h"
#include "nla_intern.h" /* own include */
/* ******************** default callbacks for nla space ***************** */
@@ -324,12 +322,11 @@ static void nla_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void nla_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -364,12 +361,11 @@ static void nla_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -423,14 +419,14 @@ static void nla_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void nla_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
@@ -465,12 +461,11 @@ static void nla_main_region_message_subscribe(const struct bContext *UNUSED(C),
}
}
-static void nla_channel_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_channel_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -508,14 +503,13 @@ static void nla_channel_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_channel_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void nla_channel_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
@@ -543,11 +537,11 @@ static void nla_channel_region_message_subscribe(const struct bContext *UNUSED(C
}
/* editor level listener */
-static void nla_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void nla_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index f2ee94af9b3..4716f1c29ea 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -190,7 +190,7 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA
cumap->flag &= ~CUMA_DRAW_SAMPLE;
}
- /* "Tone" (Standard/Filmlike) only used in the Compositor. */
+ /* "Tone" (Standard/Film-like) only used in the Compositor. */
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
uiTemplateCurveMapping(
layout, ptr, "mapping", 'c', false, false, false, (ntree->type == NTREE_COMPOSIT));
@@ -441,7 +441,7 @@ static void node_draw_frame(const bContext *C,
const rctf *rct = &node->totr;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
+ UI_draw_roundbox_aa(rct, true, BASIS_RAD, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
@@ -452,11 +452,11 @@ static void node_draw_frame(const bContext *C,
UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color);
}
- UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
+ UI_draw_roundbox_aa(rct, false, BASIS_RAD, color);
}
/* label */
- node_draw_frame_label(ntree, node, snode->aspect);
+ node_draw_frame_label(ntree, node, snode->runtime->aspect);
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
@@ -559,7 +559,7 @@ static void node_draw_reroute(const bContext *C,
if (node->flag & SELECT) {
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
- /* using different shades of TH_TEXT_HI for the empasis, like triangle */
+ /* Using different shades of #TH_TEXT_HI for the emphasis, like triangle. */
if (node->flag & NODE_ACTIVE) {
UI_GetThemeColorShadeAlpha4fv(TH_TEXT_HI, 0, -40, debug_color);
}
@@ -3126,270 +3126,6 @@ static void node_texture_set_butfunc(bNodeType *ntype)
}
}
-/* ****************** BUTTON CALLBACKS FOR GEOMETRY NODES ***************** */
-
-static void node_geometry_buts_boolean_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_compare(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("Type A"), ICON_NONE);
- uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE);
-}
-
-static void node_geometry_buts_subdivision_surface(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr))
-{
-#ifndef WITH_OPENSUBDIV
- uiItemL(layout, IFACE_("Disabled, built without OpenSubdiv"), ICON_ERROR);
-#else
- UNUSED_VARS(layout);
-#endif
-}
-
-static void node_geometry_buts_triangulate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "quad_method", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "ngon_method", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_random_attribute(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_math(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("Type A"), ICON_NONE);
- uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_vector_math(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- bNode *node = (bNode *)ptr->data;
- NodeAttributeVectorMath *node_storage = (NodeAttributeVectorMath *)node->storage;
-
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("Type A"), ICON_NONE);
-
- /* These "use input b / c" checks are copied from the node's code.
- * They could be de-duplicated if the drawing code was moved to the node's file. */
- if (!ELEM(node_storage->operation,
- NODE_VECTOR_MATH_NORMALIZE,
- NODE_VECTOR_MATH_FLOOR,
- NODE_VECTOR_MATH_CEIL,
- NODE_VECTOR_MATH_FRACTION,
- NODE_VECTOR_MATH_ABSOLUTE,
- NODE_VECTOR_MATH_SINE,
- NODE_VECTOR_MATH_COSINE,
- NODE_VECTOR_MATH_TANGENT,
- NODE_VECTOR_MATH_LENGTH)) {
- uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE);
- }
- if (ELEM(node_storage->operation, NODE_VECTOR_MATH_WRAP)) {
- uiItemR(layout, ptr, "input_type_c", DEFAULT_FLAGS, IFACE_("Type C"), ICON_NONE);
- }
-}
-
-static void node_geometry_buts_point_instance(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "instance_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- if (RNA_enum_get(ptr, "instance_type") == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION) {
- uiItemR(layout, ptr, "use_whole_collection", DEFAULT_FLAGS, NULL, ICON_NONE);
- }
-}
-
-static void node_geometry_buts_attribute_fill(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", DEFAULT_FLAGS, "", ICON_NONE);
- // uiItemR(layout, ptr, "domain", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_mix(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "blend_type", DEFAULT_FLAGS, "", ICON_NONE);
- uiLayout *col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "input_type_factor", DEFAULT_FLAGS, IFACE_("Factor"), ICON_NONE);
- uiItemR(col, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("A"), ICON_NONE);
- uiItemR(col, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("B"), ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_point_distribute(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "distribute_method", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_color_ramp(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
-}
-
-static void node_geometry_buts_point_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- NodeGeometryRotatePoints *storage = (NodeGeometryRotatePoints *)((bNode *)ptr->data)->storage;
-
- uiItemR(layout, ptr, "type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiItemR(layout, ptr, "space", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-
- uiLayout *col = uiLayoutColumn(layout, false);
- if (storage->type == GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE) {
- uiItemR(col, ptr, "input_type_axis", DEFAULT_FLAGS, IFACE_("Axis"), ICON_NONE);
- uiItemR(col, ptr, "input_type_angle", DEFAULT_FLAGS, IFACE_("Angle"), ICON_NONE);
- }
- else {
- uiItemR(col, ptr, "input_type_rotation", DEFAULT_FLAGS, IFACE_("Rotation"), ICON_NONE);
- }
-}
-
-static void node_geometry_buts_align_rotation_to_vector(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiLayout *col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "input_type_factor", DEFAULT_FLAGS, IFACE_("Factor"), ICON_NONE);
- uiItemR(col, ptr, "input_type_vector", DEFAULT_FLAGS, IFACE_("Vector"), ICON_NONE);
-}
-static void node_geometry_buts_point_translate(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "input_type", DEFAULT_FLAGS, IFACE_("Type"), ICON_NONE);
-}
-
-static void node_geometry_buts_point_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "input_type", DEFAULT_FLAGS, IFACE_("Type"), ICON_NONE);
-}
-
-static void node_geometry_buts_object_info(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "transform_space", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-}
-
-static void node_geometry_set_butfunc(bNodeType *ntype)
-{
- switch (ntype->type) {
- case GEO_NODE_BOOLEAN:
- ntype->draw_buttons = node_geometry_buts_boolean_math;
- break;
- case GEO_NODE_SUBDIVISION_SURFACE:
- ntype->draw_buttons = node_geometry_buts_subdivision_surface;
- break;
- case GEO_NODE_TRIANGULATE:
- ntype->draw_buttons = node_geometry_buts_triangulate;
- break;
- case GEO_NODE_ATTRIBUTE_RANDOMIZE:
- ntype->draw_buttons = node_geometry_buts_random_attribute;
- break;
- case GEO_NODE_ATTRIBUTE_MATH:
- ntype->draw_buttons = node_geometry_buts_attribute_math;
- break;
- case GEO_NODE_ATTRIBUTE_COMPARE:
- ntype->draw_buttons = node_geometry_buts_attribute_compare;
- break;
- case GEO_NODE_POINT_INSTANCE:
- ntype->draw_buttons = node_geometry_buts_point_instance;
- break;
- case GEO_NODE_ATTRIBUTE_FILL:
- ntype->draw_buttons = node_geometry_buts_attribute_fill;
- break;
- case GEO_NODE_ATTRIBUTE_MIX:
- ntype->draw_buttons = node_geometry_buts_attribute_mix;
- break;
- case GEO_NODE_ATTRIBUTE_VECTOR_MATH:
- ntype->draw_buttons = node_geometry_buts_attribute_vector_math;
- break;
- case GEO_NODE_POINT_DISTRIBUTE:
- ntype->draw_buttons = node_geometry_buts_attribute_point_distribute;
- break;
- case GEO_NODE_ATTRIBUTE_COLOR_RAMP:
- ntype->draw_buttons = node_geometry_buts_attribute_color_ramp;
- break;
- case GEO_NODE_POINT_ROTATE:
- ntype->draw_buttons = node_geometry_buts_point_rotate;
- break;
- case GEO_NODE_ALIGN_ROTATION_TO_VECTOR:
- ntype->draw_buttons = node_geometry_buts_align_rotation_to_vector;
- break;
- case GEO_NODE_POINT_TRANSLATE:
- ntype->draw_buttons = node_geometry_buts_point_translate;
- break;
- case GEO_NODE_POINT_SCALE:
- ntype->draw_buttons = node_geometry_buts_point_scale;
- break;
- case GEO_NODE_OBJECT_INFO:
- ntype->draw_buttons = node_geometry_buts_object_info;
- break;
- }
-}
-
-/* ****************** BUTTON CALLBACKS FOR FUNCTION NODES ***************** */
-
-static void node_function_buts_boolean_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_function_buts_float_compare(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_function_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_function_buts_input_vector(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayout *col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "vector", UI_ITEM_R_EXPAND, "", ICON_NONE);
-}
-
-static void node_function_set_butfunc(bNodeType *ntype)
-{
- switch (ntype->type) {
- case FN_NODE_BOOLEAN_MATH:
- ntype->draw_buttons = node_function_buts_boolean_math;
- break;
- case FN_NODE_FLOAT_COMPARE:
- ntype->draw_buttons = node_function_buts_float_compare;
- break;
- case FN_NODE_SWITCH:
- ntype->draw_buttons = node_function_buts_switch;
- break;
- case FN_NODE_INPUT_VECTOR:
- ntype->draw_buttons = node_function_buts_input_vector;
- break;
- }
-}
-
/* ****** init draw callbacks for all tree types, only called in usiblender.c, once ************ */
static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -3489,8 +3225,6 @@ void ED_node_init_butfuncs(void)
ntype->draw_nodetype_prepare = node_update_default;
ntype->select_area_func = node_select_area_default;
ntype->tweak_area_func = node_tweak_area_default;
- ntype->draw_buttons = NULL;
- ntype->draw_buttons_ex = NULL;
ntype->resize_area_func = node_resize_area_default;
node_common_set_butfunc(ntype);
@@ -3498,8 +3232,6 @@ void ED_node_init_butfuncs(void)
node_composit_set_butfunc(ntype);
node_shader_set_butfunc(ntype);
node_texture_set_butfunc(ntype);
- node_geometry_set_butfunc(ntype);
- node_function_set_butfunc(ntype);
/* define update callbacks for socket properties */
node_template_properties_update(ntype);
@@ -3828,18 +3560,18 @@ void draw_nodespace_back_pix(const bContext *C,
}
/* return quadratic beziers points for a given nodelink and clip if v2d is not NULL. */
-static bool node_link_bezier_handles(View2D *v2d,
- SpaceNode *snode,
- bNodeLink *link,
- float vec[4][2])
+bool node_link_bezier_handles(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
+ float vec[4][2])
{
float cursor[2] = {0.0f, 0.0f};
/* this function can be called with snode null (via cut_links_intersect) */
- /* XXX map snode->cursor back to view space */
+ /* XXX map snode->runtime->cursor back to view space */
if (snode) {
- cursor[0] = snode->cursor[0] * UI_DPI_FAC;
- cursor[1] = snode->cursor[1] * UI_DPI_FAC;
+ cursor[0] = snode->runtime->cursor[0] * UI_DPI_FAC;
+ cursor[1] = snode->runtime->cursor[1] * UI_DPI_FAC;
}
/* in v0 and v3 we put begin/end points */
@@ -3859,6 +3591,9 @@ static bool node_link_bezier_handles(View2D *v2d,
if (link->tosock) {
vec[3][0] = link->tosock->locx;
vec[3][1] = link->tosock->locy;
+ if (!(link->tonode->flag & NODE_HIDDEN) && link->tosock->flag & SOCK_MULTI_INPUT) {
+ node_link_calculate_multi_input_position(link, vec[3]);
+ }
toreroute = (link->tonode && link->tonode->type == NODE_REROUTE);
}
else {
@@ -3923,8 +3658,11 @@ static bool node_link_bezier_handles(View2D *v2d,
}
/* if v2d not NULL, it clips and returns 0 if not visible */
-bool node_link_bezier_points(
- View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
+bool node_link_bezier_points(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
+ float coord_array[][2],
+ const int resol)
{
float vec[4][2];
@@ -4087,7 +3825,7 @@ static char nodelink_get_color_id(int th_col)
return 0;
}
-static void nodelink_batch_draw(SpaceNode *snode)
+static void nodelink_batch_draw(const SpaceNode *snode)
{
if (g_batch_link.count == 0) {
return;
@@ -4107,7 +3845,7 @@ static void nodelink_batch_draw(SpaceNode *snode)
GPU_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST);
GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, colors);
- GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->runtime->aspect * LINK_WIDTH);
GPU_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE);
GPU_batch_draw(g_batch_link.batch);
@@ -4127,7 +3865,7 @@ void nodelink_batch_end(SpaceNode *snode)
g_batch_link.enabled = false;
}
-static void nodelink_batch_add_link(SpaceNode *snode,
+static void nodelink_batch_add_link(const SpaceNode *snode,
const float p0[2],
const float p1[2],
const float p2[2],
@@ -4159,11 +3897,15 @@ static void nodelink_batch_add_link(SpaceNode *snode,
}
/* don't do shadows if th_col3 is -1. */
-void node_draw_link_bezier(
- View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int th_col3)
+void node_draw_link_bezier(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
+ int th_col1,
+ int th_col2,
+ int th_col3)
{
float vec[4][2];
-
+ const bool highlighted = link->flag & NODE_LINK_TEMP_HIGHLIGHT;
if (node_link_bezier_handles(v2d, snode, link, vec)) {
int drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) &&
(link->fromnode && (link->fromnode->type == NODE_REROUTE)));
@@ -4172,7 +3914,7 @@ void node_draw_link_bezier(
nodelink_batch_init();
}
- if (g_batch_link.enabled) {
+ if (g_batch_link.enabled && !highlighted) {
/* Add link to batch. */
nodelink_batch_add_link(
snode, vec[0], vec[1], vec[2], vec[3], th_col1, th_col2, th_col3, drawarrow);
@@ -4186,11 +3928,17 @@ void node_draw_link_bezier(
UI_GetThemeColor4fv(th_col1, colors[1]);
UI_GetThemeColor4fv(th_col2, colors[2]);
+ if (highlighted) {
+ float link_preselection_highlight_color[4];
+ UI_GetThemeColor4fv(TH_SELECT, link_preselection_highlight_color);
+ copy_v4_v4(colors[2], link_preselection_highlight_color);
+ }
+
GPUBatch *batch = g_batch_link.batch_single;
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, vec);
GPU_batch_uniform_4fv_array(batch, "colors", 3, colors);
- GPU_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GPU_batch_uniform_1f(batch, "expandSize", snode->runtime->aspect * LINK_WIDTH);
GPU_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE);
GPU_batch_uniform_1i(batch, "doArrow", drawarrow);
GPU_batch_draw(batch);
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 508c0a47e21..e665f7b1d52 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -104,9 +104,8 @@ static bool add_reroute_intersect_check(bNodeLink *link,
if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
for (int i = 0; i < tot - 1; i++) {
for (int b = 0; b < NODE_LINK_RESOL; b++) {
- if (isect_seg_seg_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) {
- result[0] = (mcoords[i][0] + mcoords[i + 1][0]) / 2.0f;
- result[1] = (mcoords[i][1] + mcoords[i + 1][1]) / 2.0f;
+ if (isect_seg_seg_v2_point(
+ mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1], result) > 0) {
return true;
}
}
@@ -312,6 +311,13 @@ void NODE_OT_add_reroute(wmOperatorType *ot)
/* ****************** Add File Node Operator ******************* */
+static bool node_add_file_poll(bContext *C)
+{
+ const SpaceNode *snode = CTX_wm_space_node(C);
+ return ED_operator_node_editable(C) &&
+ ELEM(snode->nodetree->type, NTREE_SHADER, NTREE_TEXTURE, NTREE_COMPOSIT);
+}
+
static int node_add_file_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -341,7 +347,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- node = node_add_node(C, NULL, type, snode->cursor[0], snode->cursor[1]);
+ node = node_add_node(C, NULL, type, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
@@ -370,11 +376,14 @@ static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *even
SpaceNode *snode = CTX_wm_space_node(C);
/* convert mouse coordinates to v2d space */
- UI_view2d_region_to_view(
- &region->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
+ UI_view2d_region_to_view(&region->v2d,
+ event->mval[0],
+ event->mval[1],
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
if (RNA_struct_property_is_set(op->ptr, "filepath") ||
RNA_struct_property_is_set(op->ptr, "name")) {
@@ -393,7 +402,7 @@ void NODE_OT_add_file(wmOperatorType *ot)
/* callbacks */
ot->exec = node_add_file_exec;
ot->invoke = node_add_file_invoke;
- ot->poll = ED_operator_node_editable;
+ ot->poll = node_add_file_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -435,7 +444,8 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]);
+ node = node_add_node(
+ C, NULL, CMP_NODE_MASK, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add a mask node");
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index c9a0c827a09..fa4d6997c83 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -40,7 +40,6 @@
#include "RNA_access.h"
-#include "ED_gpencil.h"
#include "ED_screen.h"
#include "UI_resources.h"
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index d3fec7257f5..9ef914af75b 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -22,6 +22,8 @@
* \brief higher level node drawing for the node editor.
*/
+#include "MEM_guardedalloc.h"
+
#include "DNA_light_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
@@ -317,14 +319,14 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree)
}
}
-void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry)
+void node_to_view(const bNode *node, float x, float y, float *rx, float *ry)
{
nodeToView(node, x, y, rx, ry);
*rx *= UI_DPI_FAC;
*ry *= UI_DPI_FAC;
}
-void node_to_updated_rect(struct bNode *node, rctf *r_rect)
+void node_to_updated_rect(const bNode *node, rctf *r_rect)
{
node_to_view(node, node->offsetx, node->offsety, &r_rect->xmin, &r_rect->ymax);
node_to_view(node,
@@ -334,7 +336,7 @@ void node_to_updated_rect(struct bNode *node, rctf *r_rect)
&r_rect->ymin);
}
-void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry)
+void node_from_view(const bNode *node, float x, float y, float *rx, float *ry)
{
x /= UI_DPI_FAC;
y /= UI_DPI_FAC;
@@ -500,6 +502,16 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
PointerRNA sockptr;
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr);
+ /* Add the half the height of a multi-input socket to cursor Y
+ * to account for the increased height of the taller sockets. */
+ float multi_input_socket_offset = 0.0f;
+ if (nsock->flag & SOCK_MULTI_INPUT) {
+ if (nsock->total_inputs > 2) {
+ multi_input_socket_offset = (nsock->total_inputs - 2) * NODE_MULTI_INPUT_LINK_GAP;
+ }
+ }
+ dy -= multi_input_socket_offset * 0.5f;
+
uiLayout *layout = UI_block_layout(node->block,
UI_LAYOUT_VERTICAL,
UI_LAYOUT_PANEL,
@@ -533,7 +545,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* place the socket circle in the middle of the layout */
nsock->locy = 0.5f * (dy + buty);
- dy = buty;
+ dy = buty - multi_input_socket_offset * 0.5;
if (nsock->next) {
dy -= NODE_SOCKDY;
}
@@ -689,11 +701,11 @@ int node_get_colorid(bNode *node)
/* note: in cmp_util.c is similar code, for node_compo_pass_on()
* the same goes for shader and texture nodes. */
/* note: in node_edit.c is similar code, for untangle node */
-static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node)
+static void node_draw_mute_line(const View2D *v2d, const SpaceNode *snode, const bNode *node)
{
GPU_blend(GPU_BLEND_ALPHA);
- LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
+ LISTBASE_FOREACH (const bNodeLink *, link, &node->internal_links) {
node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1);
}
@@ -751,6 +763,27 @@ static void node_socket_draw(const bNodeSocket *sock,
immVertex2f(pos_id, locx, locy);
}
+static void node_socket_draw_multi_input(const float color[4],
+ const float color_outline[4],
+ const float width,
+ const float height,
+ const int locx,
+ const int locy)
+{
+ const float outline_width = 1.0f;
+ /* UI_draw_roundbox draws the outline on the outer side, so compensate for the outline width. */
+ const rctf rect = {
+ .xmin = locx - width + outline_width * 0.5f,
+ .xmax = locx + width - outline_width * 0.5f,
+ .ymin = locy - height + outline_width * 0.5f,
+ .ymax = locy + height - outline_width * 0.5f,
+ };
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv_ex(
+ &rect, color, NULL, 1.0f, color_outline, outline_width, width - outline_width * 0.5f);
+}
+
static void node_socket_outline_color_get(bool selected, float r_outline_color[4])
{
if (selected) {
@@ -947,14 +980,14 @@ static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_
WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, NULL);
}
-void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
+void node_draw_shadow(const SpaceNode *snode, const bNode *node, float radius, float alpha)
{
- rctf *rct = &node->totr;
+ const rctf *rct = &node->totr;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT);
+ ui_draw_dropshadow(rct, radius, snode->runtime->aspect, alpha, node->flag & SELECT);
}
-void node_draw_sockets(View2D *v2d,
+void node_draw_sockets(const View2D *v2d,
const bContext *C,
bNodeTree *ntree,
bNode *node,
@@ -1006,6 +1039,10 @@ void node_draw_sockets(View2D *v2d,
selected_input_len++;
continue;
}
+ /* Don't draw multi-input sockets here since they are drawn in a different batch. */
+ if (sock->flag & SOCK_MULTI_INPUT) {
+ continue;
+ }
node_socket_draw_nested(C,
ntree,
@@ -1115,11 +1152,33 @@ void node_draw_sockets(View2D *v2d,
GPU_program_point_size(false);
GPU_blend(GPU_BLEND_NONE);
+
+ /* Draw multi-nput sockets after the others because they are drawn with "UI_roundbox"
+ * rather than with GL_POINT. */
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ if (nodeSocketIsHidden(socket)) {
+ continue;
+ }
+ if (!(socket->flag & SOCK_MULTI_INPUT)) {
+ continue;
+ }
+
+ const bool is_node_hidden = (node->flag & NODE_HIDDEN);
+ const float width = NODE_SOCKSIZE;
+ float height = is_node_hidden ? width : node_socket_calculate_height(socket) - width;
+
+ float color[4];
+ float outline_color[4];
+ node_socket_color_get((bContext *)C, ntree, &node_ptr, socket, color);
+ node_socket_outline_color_get(selected, outline_color);
+
+ node_socket_draw_multi_input(color, outline_color, width, height, socket->locx, socket->locy);
+ }
}
static void node_draw_basis(const bContext *C,
- ARegion *region,
- SpaceNode *snode,
+ const View2D *v2d,
+ const SpaceNode *snode,
bNodeTree *ntree,
bNode *node,
bNodeInstanceKey key)
@@ -1127,8 +1186,6 @@ static void node_draw_basis(const bContext *C,
/* float socket_size = NODE_SOCKSIZE*U.dpi/72; */ /* UNUSED */
float iconbutw = 0.8f * UI_UNIT_X;
- View2D *v2d = &region->v2d;
-
/* skip if out of view */
if (BLI_rctf_isect(&node->totr, &v2d->cur, NULL) == false) {
UI_block_end(C, node->block);
@@ -1157,7 +1214,15 @@ static void node_draw_basis(const bContext *C,
rctf *rct = &node->totr;
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
UI_draw_roundbox_aa(
- true, rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD, color);
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymax - NODE_DY,
+ .ymax = rct->ymax,
+ },
+ true,
+ BASIS_RAD,
+ color);
/* show/hide icons */
float iconofs = rct->xmax - 0.35f * U.widget_unit;
@@ -1308,7 +1373,15 @@ static void node_draw_basis(const bContext *C,
UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
UI_draw_roundbox_aa(
- true, rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD, color);
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymin,
+ .ymax = rct->ymax - NODE_DY,
+ },
+ true,
+ BASIS_RAD,
+ color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
@@ -1316,7 +1389,16 @@ static void node_draw_basis(const bContext *C,
(node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymin,
+ .ymax = rct->ymax,
+ },
+ false,
+ BASIS_RAD,
+ color);
}
/* disable lines */
@@ -1343,8 +1425,8 @@ static void node_draw_basis(const bContext *C,
}
static void node_draw_hidden(const bContext *C,
- ARegion *region,
- SpaceNode *snode,
+ const View2D *v2d,
+ const SpaceNode *snode,
bNodeTree *ntree,
bNode *node,
bNodeInstanceKey UNUSED(key))
@@ -1353,8 +1435,6 @@ static void node_draw_hidden(const bContext *C,
float centy = BLI_rctf_cent_y(rct);
float hiddenrad = BLI_rctf_size_y(rct) / 2.0f;
- View2D *v2d = &region->v2d;
-
float scale;
UI_view2d_scale_get(v2d, &scale, NULL);
@@ -1373,14 +1453,14 @@ static void node_draw_hidden(const bContext *C,
UI_GetThemeColor4fv(color_id, color);
}
- UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
+ UI_draw_roundbox_aa(rct, true, hiddenrad, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
UI_GetThemeColorShadeAlpha4fv(
(node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
- UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
+ UI_draw_roundbox_aa(rct, false, hiddenrad, color);
}
/* custom color inline */
@@ -1388,14 +1468,17 @@ static void node_draw_hidden(const bContext *C,
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
- UI_draw_roundbox_3fv_alpha(false,
- rct->xmin + 1,
- rct->ymin + 1,
- rct->xmax - 1,
- rct->ymax - 1,
- hiddenrad,
- node->color,
- 1.0f);
+ UI_draw_roundbox_3fv_alpha(
+ &(const rctf){
+ .xmin = rct->xmin + 1,
+ .xmax = rct->xmax - 1,
+ .ymin = rct->ymin + 1,
+ .ymax = rct->ymax - 1,
+ },
+ false,
+ hiddenrad,
+ node->color,
+ 1.0f);
GPU_line_smooth(false);
GPU_blend(GPU_BLEND_NONE);
@@ -1438,7 +1521,7 @@ static void node_draw_hidden(const bContext *C,
/* disable lines */
if (node->flag & NODE_MUTED) {
- node_draw_mute_line(&region->v2d, snode, node);
+ node_draw_mute_line(v2d, snode, node);
}
char showname[128]; /* 128 is used below */
@@ -1477,19 +1560,19 @@ static void node_draw_hidden(const bContext *C,
immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy + 4.0f);
immEnd();
immUniformThemeColorShade(color_id, 30);
- dx -= snode->aspect;
+ dx -= snode->runtime->aspect;
immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy + 4.0f);
immEnd();
immUnbindProgram();
@@ -1550,11 +1633,12 @@ void node_draw_default(const bContext *C,
bNode *node,
bNodeInstanceKey key)
{
+ const View2D *v2d = &region->v2d;
if (node->flag & NODE_HIDDEN) {
- node_draw_hidden(C, region, snode, ntree, node, key);
+ node_draw_hidden(C, v2d, snode, ntree, node, key);
}
else {
- node_draw_basis(C, region, snode, ntree, node, key);
+ node_draw_basis(C, v2d, snode, ntree, node, key);
}
}
@@ -1565,17 +1649,67 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node)
}
}
+static void count_mutli_input_socket_links(bNodeTree *ntree, SpaceNode *snode)
+{
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ LISTBASE_FOREACH (struct bNodeSocket *, socket, &node->inputs) {
+ if (socket->flag & SOCK_MULTI_INPUT) {
+ socket->total_inputs = 0;
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ if (link->tosock == socket) {
+ socket->total_inputs++;
+ }
+ }
+ /* Count temporary links going into this socket. */
+ LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
+ LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
+ bNodeLink *link = (bNodeLink *)linkdata->data;
+ if (link->tosock == socket) {
+ socket->total_inputs++;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
void node_update_nodetree(const bContext *C, bNodeTree *ntree)
{
/* make sure socket "used" tags are correct, for displaying value buttons */
+ SpaceNode *snode = CTX_wm_space_node(C);
ntreeTagUsedSockets(ntree);
+ count_mutli_input_socket_links(ntree, snode);
+
/* update nodes front to back, so children sizes get updated before parents */
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree->nodes) {
node_update(C, ntree, node);
}
}
+static int compare_link_by_angle_to_node(const void *a, const void *b)
+{
+ const bNodeLink *link_a = *(const bNodeLink **)a;
+ const bNodeLink *link_b = *(const bNodeLink **)b;
+
+ BLI_assert(link_a->tosock == link_b->tosock);
+ const float socket_location[2] = {link_a->tosock->locx, link_a->tosock->locy};
+ const float up_direction[2] = {0.0f, 1.0f};
+
+ float delta_a[2] = {link_a->fromsock->locx - socket_location[0],
+ link_a->fromsock->locy - socket_location[1]};
+ normalize_v2(delta_a);
+ const float angle_a = angle_normalized_v2v2(up_direction, delta_a);
+
+ float delta_b[2] = {link_b->fromsock->locx - socket_location[0],
+ link_b->fromsock->locy - socket_location[1]};
+ normalize_v2(delta_b);
+ const float angle_b = angle_normalized_v2v2(up_direction, delta_b);
+
+ return angle_a < angle_b ? 1 : -1;
+}
+
static void node_draw(const bContext *C,
ARegion *region,
SpaceNode *snode,
@@ -1590,6 +1724,46 @@ static void node_draw(const bContext *C,
#define USE_DRAW_TOT_UPDATE
+/**
+ * Automatically sort the input links to multi-input sockets to avoid crossing noodles.
+ */
+static void sort_multi_input_socket_links(bNodeTree *ntree, SpaceNode *snode)
+{
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ if (socket->flag & SOCK_MULTI_INPUT) {
+ /* The total is calculated in #node_update_nodetree, which runs before this draw step. */
+ const int total_inputs = socket->total_inputs;
+ bNodeLink **input_links = MEM_malloc_arrayN(total_inputs, sizeof(bNodeLink *), __func__);
+
+ int index = 0;
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ if (link->tosock == socket) {
+ input_links[index] = (bNodeLink *)link;
+ index++;
+ }
+ }
+ LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
+ LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
+ bNodeLink *link = (bNodeLink *)linkdata->data;
+ if (link->tosock == socket) {
+ input_links[index] = (bNodeLink *)link;
+ index++;
+ }
+ }
+ }
+
+ qsort(input_links, total_inputs, sizeof(bNodeLink *), compare_link_by_angle_to_node);
+ for (int i = 0; i < total_inputs; i++) {
+ input_links[i]->multi_input_socket_index = i;
+ }
+
+ MEM_freeN(input_links);
+ }
+ }
+ }
+}
+
void node_draw_nodetree(const bContext *C,
ARegion *region,
SpaceNode *snode,
@@ -1607,8 +1781,7 @@ void node_draw_nodetree(const bContext *C,
#endif
/* draw background nodes, last nodes in front */
- int a = 0;
- LISTBASE_FOREACH_INDEX (bNode *, node, &ntree->nodes, a) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
#ifdef USE_DRAW_TOT_UPDATE
/* unrelated to background nodes, update the v2d->tot,
* can be anywhere before we draw the scroll bars */
@@ -1626,6 +1799,9 @@ void node_draw_nodetree(const bContext *C,
/* node lines */
GPU_blend(GPU_BLEND_ALPHA);
nodelink_batch_start(snode);
+
+ sort_multi_input_socket_links(ntree, snode);
+
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
if (!nodeLinkIsHidden(link)) {
node_draw_link(&region->v2d, snode, link);
@@ -1635,8 +1811,7 @@ void node_draw_nodetree(const bContext *C,
GPU_blend(GPU_BLEND_NONE);
/* draw foreground nodes, last nodes in front */
- a = 0;
- LISTBASE_FOREACH_INDEX (bNode *, node, &ntree->nodes, a) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->flag & NODE_BACKGROUND) {
continue;
}
@@ -1666,7 +1841,7 @@ static void snode_setup_v2d(SpaceNode *snode, ARegion *region, const float cente
UI_view2d_view_ortho(v2d);
/* aspect+font, set each time */
- snode->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);
}
@@ -1686,8 +1861,8 @@ static void draw_nodetree(const bContext *C,
/* shade the parent node group and add a uiBlock to clip mouse events */
static void draw_group_overlay(const bContext *C, ARegion *region)
{
- View2D *v2d = &region->v2d;
- rctf rect = v2d->cur;
+ const View2D *v2d = &region->v2d;
+ const rctf rect = v2d->cur;
float color[4];
/* shade node groups to separate them visually */
@@ -1695,7 +1870,7 @@ static void draw_group_overlay(const bContext *C, ARegion *region)
UI_GetThemeColorShadeAlpha4fv(TH_NODE_GROUP, 0, 0, color);
UI_draw_roundbox_corner_set(UI_CNR_NONE);
- UI_draw_roundbox_4fv(true, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0, color);
+ UI_draw_roundbox_4fv(&rect, true, 0, color);
GPU_blend(GPU_BLEND_NONE);
/* set the block bounds to clip mouse events from underlying nodes */
@@ -1722,14 +1897,15 @@ void node_draw_space(const bContext *C, ARegion *region)
GPU_depth_test(GPU_DEPTH_NONE);
GPU_scissor_test(true);
- /* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */
+ /* XXX snode->runtime->cursor set in coordspace for placing new nodes, used for drawing noodles
+ * too */
UI_view2d_region_to_view(&region->v2d,
win->eventstate->x - region->winrct.xmin,
win->eventstate->y - region->winrct.ymin,
- &snode->cursor[0],
- &snode->cursor[1]);
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
int grid_levels = UI_GetThemeValueType(TH_NODE_GRID_LEVELS, SPACE_NODE);
@@ -1819,7 +1995,7 @@ void node_draw_space(const bContext *C, ARegion *region)
/* temporary links */
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
- LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->linkdrag) {
+ LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
node_draw_link(v2d, snode, (bNodeLink *)linkdata->data);
}
@@ -1847,7 +2023,7 @@ void node_draw_space(const bContext *C, ARegion *region)
if (snode->treepath.last) {
if (snode->flag & SNODE_SHOW_GPENCIL) {
- /* draw grease-pencil (screen strokes, and also paintbuffer) */
+ /* Draw grease-pencil (screen strokes, and also paint-buffer). */
ED_annotation_draw_view2d(C, false);
}
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 30eee416b12..04787748937 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -98,6 +98,25 @@ typedef struct CompoJob {
float *progress;
} CompoJob;
+float node_socket_calculate_height(const bNodeSocket *socket)
+{
+ float sock_height = NODE_SOCKSIZE * 2.0f;
+ if (socket->flag & SOCK_MULTI_INPUT) {
+ sock_height += max_ii(NODE_MULTI_INPUT_LINK_GAP * 0.5f * socket->total_inputs, NODE_SOCKSIZE);
+ }
+ return sock_height;
+}
+
+void node_link_calculate_multi_input_position(const bNodeLink *link, float r[2])
+{
+ float offset = (link->tosock->total_inputs * NODE_MULTI_INPUT_LINK_GAP -
+ NODE_MULTI_INPUT_LINK_GAP) *
+ 0.5;
+ r[0] = link->tosock->locx - NODE_SOCKSIZE * 0.5f;
+ r[1] = link->tosock->locy - offset +
+ (link->multi_input_socket_index * NODE_MULTI_INPUT_LINK_GAP);
+}
+
static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags)
{
LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
@@ -770,7 +789,7 @@ void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree))
* which only exists during actual drawing. Can we rely on valid totr rects?
*/
/* make sure nodes have correct bounding boxes after transform */
- /* node_update_nodetree(C, ntree, 0.0f, 0.0f); */
+ // node_update_nodetree(C, ntree, 0.0f, 0.0f);
}
/* ***************** generic operator functions for nodes ***************** */
@@ -880,8 +899,8 @@ static void node_resize_init(
NodeSizeWidget *nsw = MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
op->customdata = nsw;
- nsw->mxstart = snode->cursor[0] * UI_DPI_FAC;
- nsw->mystart = snode->cursor[1] * UI_DPI_FAC;
+ nsw->mxstart = snode->runtime->cursor[0] * UI_DPI_FAC;
+ nsw->mystart = snode->runtime->cursor[1] * UI_DPI_FAC;
/* store old */
nsw->oldlocx = node->locx;
@@ -1104,6 +1123,21 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
}
/* checks snode->mouse position, and returns found node/socket */
+static bool cursor_isect_multi_input_socket(const float cursor[2], const bNodeSocket *socket)
+{
+ const float node_socket_height = node_socket_calculate_height(socket);
+ const rctf multi_socket_rect = {
+ .xmin = socket->locx - NODE_SOCKSIZE * 4,
+ .xmax = socket->locx + NODE_SOCKSIZE,
+ .ymin = socket->locy - node_socket_height * 0.5 - NODE_SOCKSIZE * 2.0f,
+ .ymax = socket->locy + node_socket_height * 0.5 + NODE_SOCKSIZE * 2.0f,
+ };
+ if (BLI_rctf_isect_pt(&multi_socket_rect, cursor[0], cursor[1])) {
+ return true;
+ }
+ return false;
+}
+
/* type is SOCK_IN and/or SOCK_OUT */
int node_find_indicated_socket(
SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, float cursor[2], int in_out)
@@ -1132,7 +1166,16 @@ int node_find_indicated_socket(
if (in_out & SOCK_IN) {
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (!nodeSocketIsHidden(sock)) {
- if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
+ if (sock->flag & SOCK_MULTI_INPUT && !(node->flag & NODE_HIDDEN)) {
+ if (cursor_isect_multi_input_socket(cursor, sock)) {
+ if (node == visible_node(snode, &rect)) {
+ *nodep = node;
+ *sockp = sock;
+ return 1;
+ }
+ }
+ }
+ else if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
if (node == visible_node(snode, &rect)) {
*nodep = node;
*sockp = sock;
@@ -1199,7 +1242,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
if (node->flag & SELECT) {
BKE_node_copy_store_new_pointers(ntree, node, LIB_ID_COPY_DEFAULT);
- /* to ensure redraws or rerenders happen */
+ /* To ensure redraws or re-renders happen. */
ED_node_tag_update_id(snode->id);
}
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index f2abe272f48..7f530408ec7 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -1039,7 +1039,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
- /* We broke relations in node tree, need to rebuild them in the grahes. */
+ /* We broke relations in node tree, need to rebuild them in the graphs. */
DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index aa59b7293a3..2f3fa6996af 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -37,6 +37,7 @@ struct bContext;
struct bNode;
struct bNodeLink;
struct bNodeSocket;
+struct NodeInsertOfsData;
struct wmGizmoGroupType;
struct wmKeyConfig;
struct wmWindow;
@@ -50,25 +51,49 @@ typedef struct bNodeLinkDrag {
* This way the links can be added to the node tree while being stored in this list.
*/
ListBase links;
+ bool from_multi_input_socket;
int in_out;
} bNodeLinkDrag;
+typedef struct SpaceNode_Runtime {
+ float aspect;
+
+ /** Mouse position for drawing socket-less links and adding nodes. */
+ float cursor[2];
+
+ /** For auto compositing. */
+ bool recalc;
+
+ /** Temporary data for modal linking operator. */
+ struct ListBase linkdrag;
+
+ /* 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;
+} SpaceNode_Runtime;
+
/* space_node.c */
/* transform between View2Ds in the tree path */
void space_node_group_offset(struct SpaceNode *snode, float *x, float *y);
/* node_draw.c */
+float node_socket_calculate_height(const bNodeSocket *socket);
+void node_link_calculate_multi_input_position(const bNodeLink *link, float r[2]);
+
int node_get_colorid(struct bNode *node);
int node_get_resize_cursor(int directions);
-void node_draw_shadow(struct SpaceNode *snode, struct bNode *node, float radius, float alpha);
+void node_draw_shadow(const struct SpaceNode *snode,
+ const struct bNode *node,
+ float radius,
+ float alpha);
void node_draw_default(const struct bContext *C,
struct ARegion *region,
struct SpaceNode *snode,
struct bNodeTree *ntree,
struct bNode *node,
bNodeInstanceKey key);
-void node_draw_sockets(struct View2D *v2d,
+void node_draw_sockets(const struct View2D *v2d,
const struct bContext *C,
struct bNodeTree *ntree,
struct bNode *node,
@@ -92,9 +117,9 @@ void node_draw_space(const bContext *C, ARegion *region);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode, float cursor[2]);
/* DPI scaled coords */
-void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry);
-void node_to_updated_rect(struct bNode *node, rctf *r_rect);
-void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry);
+void node_to_view(const struct bNode *node, float x, float y, float *rx, float *ry);
+void node_to_updated_rect(const struct bNode *node, rctf *r_rect);
+void node_from_view(const struct bNode *node, float x, float y, float *rx, float *ry);
/* node_buttons.c */
void node_buttons_register(struct ARegionType *art);
@@ -145,17 +170,21 @@ void nodelink_batch_start(struct SpaceNode *snode);
void nodelink_batch_end(struct SpaceNode *snode);
void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link);
-void node_draw_link_bezier(struct View2D *v2d,
- struct SpaceNode *snode,
- struct bNodeLink *link,
+void node_draw_link_bezier(const struct View2D *v2d,
+ const struct SpaceNode *snode,
+ const struct bNodeLink *link,
int th_col1,
int th_col2,
int th_col3);
-bool node_link_bezier_points(struct View2D *v2d,
- struct SpaceNode *snode,
- struct bNodeLink *link,
+bool node_link_bezier_points(const struct View2D *v2d,
+ const struct SpaceNode *snode,
+ const struct bNodeLink *link,
float coord_array[][2],
- int resol);
+ const int resol);
+bool node_link_bezier_handles(const struct View2D *v2d,
+ const struct SpaceNode *snode,
+ const struct bNodeLink *link,
+ float vec[4][2]);
void draw_nodespace_back_pix(const struct bContext *C,
struct ARegion *region,
struct SpaceNode *snode,
@@ -268,6 +297,7 @@ extern const char *node_context_dir[];
#define NODE_HEIGHT(node) (node->height * UI_DPI_FAC)
#define NODE_MARGIN_X (1.10f * U.widget_unit)
#define NODE_SOCKSIZE (0.25f * U.widget_unit)
+#define NODE_MULTI_INPUT_LINK_GAP (0.25f * U.widget_unit)
#define NODE_RESIZE_MARGIN (0.20f * U.widget_unit)
#define NODE_LINK_RESOL 12
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 11933ef0811..d55fd06ddea 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -23,14 +23,10 @@
#include "DNA_node_types.h"
-#include "BLI_utildefines.h"
-
#include "BKE_context.h"
#include "ED_node.h" /* own include */
#include "ED_screen.h"
-#include "ED_select_utils.h"
-#include "ED_transform.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index ba1e752e276..d6edfcce8e8 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -32,6 +32,7 @@
#include "BKE_anim_data.h"
#include "BKE_context.h"
+#include "BKE_curve.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -58,7 +59,7 @@
static bool ntree_has_drivers(bNodeTree *ntree)
{
- AnimData *adt = BKE_animdata_from_id(&ntree->id);
+ const AnimData *adt = BKE_animdata_from_id(&ntree->id);
if (adt == NULL) {
return false;
}
@@ -179,6 +180,137 @@ typedef struct NodeInsertOfsData {
float offset_x; /* offset to apply to node chain */
} NodeInsertOfsData;
+static void clear_picking_highlight(ListBase *links)
+{
+ LISTBASE_FOREACH (bNodeLink *, link, links) {
+ link->flag &= ~NODE_LINK_TEMP_HIGHLIGHT;
+ }
+}
+
+static LinkData *create_drag_link(Main *bmain, SpaceNode *snode, bNode *node, bNodeSocket *sock)
+{
+ LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
+ bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ linkdata->data = oplink;
+ if (sock->in_out == SOCK_OUT) {
+ oplink->fromnode = node;
+ oplink->fromsock = sock;
+ }
+ else {
+ oplink->tonode = node;
+ oplink->tosock = sock;
+ }
+ oplink->flag |= NODE_LINK_VALID;
+ oplink->flag &= ~NODE_LINK_TEST;
+ if (node_connected_to_output(bmain, snode->edittree, node)) {
+ oplink->flag |= NODE_LINK_TEST;
+ }
+ return linkdata;
+}
+
+static void pick_link(const bContext *C,
+ wmOperator *op,
+ bNodeLinkDrag *nldrag,
+ SpaceNode *snode,
+ bNode *node,
+ bNodeLink *link_to_pick)
+{
+ clear_picking_highlight(&snode->edittree->links);
+ RNA_boolean_set(op->ptr, "has_link_picked", true);
+
+ Main *bmain = CTX_data_main(C);
+ LinkData *linkdata = create_drag_link(
+ bmain, snode, link_to_pick->fromnode, link_to_pick->fromsock);
+
+ BLI_addtail(&nldrag->links, linkdata);
+ nodeRemLink(snode->edittree, link_to_pick);
+ /* Send changed event to original link->tonode. */
+ if (node) {
+ snode_update(snode, node);
+ }
+}
+
+static void pick_input_link_by_link_intersect(const bContext *C,
+ wmOperator *op,
+ bNodeLinkDrag *nldrag,
+ const float *cursor)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ const ARegion *region = CTX_wm_region(C);
+ const View2D *v2d = &region->v2d;
+
+ float drag_start[2];
+ RNA_float_get_array(op->ptr, "drag_start", drag_start);
+ bNode *node;
+ bNodeSocket *socket;
+ node_find_indicated_socket(snode, &node, &socket, drag_start, SOCK_IN);
+
+ const float trigger_drag_distance = 25.0f;
+ const float cursor_link_touch_distance = 25.0f;
+
+ const float socket_height = node_socket_calculate_height(socket);
+
+ float cursor_to_socket_relative[2];
+ float socket_position[2] = {socket->locx, socket->locy};
+ sub_v2_v2v2(cursor_to_socket_relative, cursor, socket_position);
+ float distance_from_socket_v2[2] = {
+ max_ff(0, fabs(cursor_to_socket_relative[0]) - NODE_SOCKSIZE * 0.5),
+ max_ff(0, fabs(cursor_to_socket_relative[1]) - socket_height)};
+ const float distance_from_socket = len_v2(distance_from_socket_v2);
+
+ const int resolution = NODE_LINK_RESOL;
+
+ bNodeLink *link_to_pick = NULL;
+ clear_picking_highlight(&snode->edittree->links);
+ LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
+ if (link->tosock == socket) {
+ /* Test if the cursor is near a link. */
+ float vec[4][2];
+ node_link_bezier_handles(v2d, snode, link, vec);
+
+ float data[NODE_LINK_RESOL * 2 + 2];
+ BKE_curve_forward_diff_bezier(
+ vec[0][0], vec[1][0], vec[2][0], vec[3][0], data, resolution, sizeof(float[2]));
+ BKE_curve_forward_diff_bezier(
+ vec[0][1], vec[1][1], vec[2][1], vec[3][1], data + 1, resolution, sizeof(float[2]));
+
+ for (int i = 0; i < resolution * 2; i += 2) {
+ float *l1 = &data[i];
+ float *l2 = &data[i + 2];
+ float distance = dist_squared_to_line_segment_v2(cursor, l1, l2);
+ if (distance < cursor_link_touch_distance) {
+ link_to_pick = link;
+ RNA_int_set(op->ptr, "last_picked_link_index", link->multi_input_socket_index);
+ }
+ }
+ }
+ }
+
+ /* If no linked was picked in this call, try using the one picked in the previous call.
+ * Not essential for the basic behavior, but can make interaction feel a bit better if
+ * the mouse moves to the right and loses the "selection." */
+ if (!link_to_pick) {
+ int last_picked_link_index = RNA_int_get(op->ptr, "last_picked_link_index");
+ if (last_picked_link_index > -1) {
+ LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
+ if (link->multi_input_socket_index == last_picked_link_index) {
+ link_to_pick = link;
+ }
+ }
+ }
+ }
+
+ if (link_to_pick) {
+ /* Highlight is set here and cleared in the next iteration or if the operation finishes. */
+ link_to_pick->flag |= NODE_LINK_TEMP_HIGHLIGHT;
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ if (distance_from_socket > trigger_drag_distance) {
+ pick_link(C, op, nldrag, snode, node, link_to_pick);
+ }
+ }
+}
+
static int sort_nodes_locx(const void *a, const void *b)
{
const bNodeListItem *nli1 = a;
@@ -600,6 +732,13 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
tlink = NULL;
to_count--;
}
+ else if (tlink->fromsock == from) {
+ /* Also remove link if it comes from the same output. */
+ nodeRemLink(ntree, tlink);
+ tlink = NULL;
+ to_count--;
+ from_count--;
+ }
}
}
}
@@ -663,7 +802,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
snode_dag_update(C, snode);
}
- BLI_remlink(&snode->linkdrag, nldrag);
+ BLI_remlink(&snode->runtime->linkdrag, nldrag);
/* links->data pointers are either held by the tree or freed already */
BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
@@ -736,7 +875,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
}
}
-/* loop that adds a nodelink, called by function below */
+/* Loop that adds a node-link, called by function below. */
/* in_out = starting socket */
static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -748,10 +887,15 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
switch (event->type) {
case MOUSEMOVE:
- node_link_find_socket(C, op, cursor);
+ if (nldrag->from_multi_input_socket && !RNA_boolean_get(op->ptr, "has_link_picked")) {
+ pick_input_link_by_link_intersect(C, op, nldrag, cursor);
+ }
+ else {
+ node_link_find_socket(C, op, cursor);
- node_link_update_header(C, nldrag);
- ED_region_tag_redraw(region);
+ node_link_update_header(C, nldrag);
+ ED_region_tag_redraw(region);
+ }
break;
case LEFTMOUSE:
@@ -762,6 +906,8 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
ED_workspace_status_text(C, NULL);
ED_region_tag_redraw(region);
+ SpaceNode *snode = CTX_wm_space_node(C);
+ clear_picking_highlight(&snode->edittree->links);
return OPERATOR_FINISHED;
}
break;
@@ -817,16 +963,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
/* dragged links are fixed on output side */
nldrag->in_out = SOCK_OUT;
/* create a new link */
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
- linkdata->data = oplink;
- oplink->fromnode = node;
- oplink->fromsock = sock;
- oplink->flag |= NODE_LINK_VALID;
- oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(bmain, snode->edittree, node)) {
- oplink->flag |= NODE_LINK_TEST;
- }
+ LinkData *linkdata = create_drag_link(bmain, snode, node, sock);
BLI_addtail(&nldrag->links, linkdata);
}
@@ -836,31 +973,38 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
const int num_links = nodeCountSocketLinks(snode->edittree, sock);
- int link_limit = nodeSocketLinkLimit(sock);
- if (num_links > 0 && (num_links >= link_limit || detach)) {
+ if (num_links > 0) {
/* dragged links are fixed on output side */
nldrag->in_out = SOCK_OUT;
/* detach current links and store them in the operator data */
+ bNodeLink *link_to_pick;
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode->edittree->links) {
if (link->tosock == sock) {
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
- linkdata->data = oplink;
- *oplink = *link;
- oplink->next = oplink->prev = NULL;
- oplink->flag |= NODE_LINK_VALID;
- oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(bmain, snode->edittree, link->tonode)) {
- oplink->flag |= NODE_LINK_TEST;
+ if (sock->flag & SOCK_MULTI_INPUT) {
+ nldrag->from_multi_input_socket = true;
}
+ link_to_pick = link;
+ }
+ }
- BLI_addtail(&nldrag->links, linkdata);
- nodeRemLink(snode->edittree, link);
+ if (link_to_pick != NULL && !nldrag->from_multi_input_socket) {
+ LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
+ bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ linkdata->data = oplink;
+ *oplink = *link_to_pick;
+ oplink->next = oplink->prev = NULL;
+ oplink->flag |= NODE_LINK_VALID;
+ oplink->flag &= ~NODE_LINK_TEST;
+ if (node_connected_to_output(bmain, snode->edittree, link_to_pick->tonode)) {
+ oplink->flag |= NODE_LINK_TEST;
+ }
- /* send changed event to original link->tonode */
- if (node) {
- snode_update(snode, node);
- }
+ BLI_addtail(&nldrag->links, linkdata);
+ nodeRemLink(snode->edittree, link_to_pick);
+
+ /* send changed event to original link->tonode */
+ if (node) {
+ snode_update(snode, node);
}
}
}
@@ -868,16 +1012,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
/* dragged links are fixed on input side */
nldrag->in_out = SOCK_IN;
/* create a new link */
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
- linkdata->data = oplink;
- oplink->tonode = node;
- oplink->tosock = sock;
- oplink->flag |= NODE_LINK_VALID;
- oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(bmain, snode->edittree, node)) {
- oplink->flag |= NODE_LINK_TEST;
- }
+ LinkData *linkdata = create_drag_link(bmain, snode, node, sock);
BLI_addtail(&nldrag->links, linkdata);
}
@@ -896,6 +1031,9 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
float cursor[2];
UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &cursor[0], &cursor[1]);
+ RNA_float_set_array(op->ptr, "drag_start", cursor);
+ RNA_int_set(op->ptr, "last_picked_link_index", -1);
+ RNA_boolean_set(op->ptr, "has_link_picked", false);
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
@@ -903,7 +1041,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (nldrag) {
op->customdata = nldrag;
- BLI_addtail(&snode->linkdrag, nldrag);
+ BLI_addtail(&snode->runtime->linkdrag, nldrag);
/* add modal handler */
WM_event_add_modal_handler(C, op);
@@ -918,10 +1056,11 @@ static void node_link_cancel(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
bNodeLinkDrag *nldrag = op->customdata;
- BLI_remlink(&snode->linkdrag, nldrag);
+ BLI_remlink(&snode->runtime->linkdrag, nldrag);
BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
+ clear_picking_highlight(&snode->edittree->links);
}
void NODE_OT_link(wmOperatorType *ot)
@@ -941,7 +1080,38 @@ void NODE_OT_link(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+ PropertyRNA *prop;
+
RNA_def_boolean(ot->srna, "detach", false, "Detach", "Detach and redirect existing links");
+ prop = RNA_def_boolean(
+ ot->srna,
+ "has_link_picked",
+ false,
+ "Has Link Picked",
+ "The operation has placed a link. Only used for multi-input sockets, where the "
+ "link is picked later");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ RNA_def_float_array(ot->srna,
+ "drag_start",
+ 2,
+ 0,
+ -UI_PRECISION_FLOAT_MAX,
+ UI_PRECISION_FLOAT_MAX,
+ "Drag Start",
+ "The position of the mouse cursor at the start of the operation",
+ -UI_PRECISION_FLOAT_MAX,
+ UI_PRECISION_FLOAT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ RNA_def_int(ot->srna,
+ "last_picked_link_index",
+ -1,
+ -1,
+ 4095,
+ "Last Picked Link Index",
+ "The index of the last picked link on a multi-input socket",
+ -1,
+ 4095);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* ********************** Make Link operator ***************** */
@@ -1513,7 +1683,7 @@ void ED_node_link_intersect_test(ScrArea *area, int test)
/* loop over link coords to find shortest dist to
* upper left node edge of a intersected line segment */
for (int i = 0; i < NODE_LINK_RESOL; i++) {
- /* check if the node rect intersetcts the line from this point to next one */
+ /* Check if the node rectangle intersects the line from this point to next one. */
if (BLI_rctf_isect_segment(&select->totr, coord_array[i], coord_array[i + 1])) {
/* store the shortest distance to the upper left edge
* of all intersections found so far */
@@ -1798,7 +1968,7 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
- NodeInsertOfsData *iofsd = snode->iofsd;
+ NodeInsertOfsData *iofsd = snode->runtime->iofsd;
bool redraw = false;
if (!snode || event->type != TIMER || iofsd == NULL || iofsd->anim_timer != event->customdata) {
@@ -1837,7 +2007,7 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
node->anim_init_locx = node->anim_ofsx = 0.0f;
}
- snode->iofsd = NULL;
+ snode->runtime->iofsd = NULL;
MEM_freeN(iofsd);
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
@@ -1851,7 +2021,7 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
static int node_insert_offset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
const SpaceNode *snode = CTX_wm_space_node(C);
- NodeInsertOfsData *iofsd = snode->iofsd;
+ NodeInsertOfsData *iofsd = snode->runtime->iofsd;
if (!iofsd || !iofsd->insert) {
return OPERATOR_CANCELLED;
@@ -1927,7 +2097,7 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
iofsd->prev = link->fromnode;
iofsd->next = node;
- snode->iofsd = iofsd;
+ snode->runtime->iofsd = iofsd;
}
ntreeUpdateTree(bmain, snode->edittree); /* needed for pointers */
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 5060ac0db8a..1e6ca66dd31 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -26,7 +26,6 @@
#include "DNA_node_types.h"
#include "DNA_windowmanager_types.h"
-#include "BLI_alloca.h"
#include "BLI_lasso_2d.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -62,14 +61,15 @@
#include "node_intern.h" /* own include */
-/* Function to detect if there is a visible view3d that uses workbench in texture mode.
+/**
+ * Function to detect if there is a visible view3d that uses workbench in texture mode.
* This function is for fixing T76970 for Blender 2.83. The actual fix should add a mechanism in
* the depsgraph that can be used by the draw engines to check if they need to be redrawn.
*
* We don't want to add these risky changes this close before releasing 2.83 without good testing
* hence this workaround. There are still cases were too many updates happen. For example when you
* have both a Cycles and workbench with textures viewport.
- * */
+ */
static bool has_workbench_in_texture_color(const wmWindowManager *wm,
const Scene *scene,
const Object *ob)
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 553971cd0a5..f0e3f5442cc 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -35,7 +35,6 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
-#include "BKE_scene.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c
index 7afd3fef4db..2e7d6ab6cd5 100644
--- a/source/blender/editors/space_node/node_toolbar.c
+++ b/source/blender/editors/space_node/node_toolbar.c
@@ -29,9 +29,6 @@
#include "BKE_screen.h"
#include "WM_api.h"
-#include "WM_types.h"
-
-#include "ED_screen.h"
#include "node_intern.h" /* own include */
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index d938cb38270..8f1dc3c8c3e 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -52,7 +52,6 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "NOD_composite.h"
#include "node_intern.h" /* own include */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index ad7632377a3..73c6a28a5dc 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -35,7 +35,6 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_node.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
#include "ED_node.h"
@@ -321,18 +320,25 @@ static void node_free(SpaceLink *sl)
LISTBASE_FOREACH_MUTABLE (bNodeTreePath *, path, &snode->treepath) {
MEM_freeN(path);
}
+
+ MEM_SAFE_FREE(snode->runtime);
}
/* spacetype; init callback */
-static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
+static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
{
+ SpaceNode *snode = (SpaceNode *)area->spacedata.first;
+
+ if (snode->runtime == NULL) {
+ snode->runtime = MEM_callocN(sizeof(SpaceNode_Runtime), __func__);
+ }
}
-static void node_area_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void node_area_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+
/* note, ED_area_tag_refresh will re-execute compositor */
SpaceNode *snode = area->spacedata.first;
/* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */
@@ -362,7 +368,7 @@ static void node_area_listener(wmWindow *UNUSED(win),
case ND_TRANSFORM_DONE:
if (ED_node_is_compositor(snode)) {
if (snode->flag & SNODE_AUTO_RENDER) {
- snode->recalc = 1;
+ snode->runtime->recalc = true;
ED_area_tag_refresh(area);
}
}
@@ -521,8 +527,8 @@ static void node_area_refresh(const struct bContext *C, ScrArea *area)
Scene *scene = (Scene *)snode->id;
if (scene->use_nodes) {
/* recalc is set on 3d view changes for auto compo */
- if (snode->recalc) {
- snode->recalc = 0;
+ if (snode->runtime->recalc) {
+ snode->runtime->recalc = false;
node_render_changed_exec((struct bContext *)C, NULL);
}
else {
@@ -546,8 +552,10 @@ static SpaceLink *node_duplicate(SpaceLink *sl)
BLI_duplicatelist(&snoden->treepath, &snode->treepath);
- /* clear or remove stuff from old */
- BLI_listbase_clear(&snoden->linkdrag);
+ if (snode->runtime != NULL) {
+ snoden->runtime = MEM_dupallocN(snode->runtime);
+ BLI_listbase_clear(&snoden->runtime->linkdrag);
+ }
/* Note: no need to set node tree user counts,
* the editor only keeps at least 1 (id_us_ensure_real),
@@ -589,6 +597,16 @@ static void node_toolbar_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
+void ED_node_cursor_location_get(const SpaceNode *snode, float value[2])
+{
+ copy_v2_v2(value, snode->runtime->cursor);
+}
+
+void ED_node_cursor_location_set(SpaceNode *snode, const float value[2])
+{
+ copy_v2_v2(snode->runtime->cursor, value);
+}
+
static void node_cursor(wmWindow *win, ScrArea *area, ARegion *region)
{
SpaceNode *snode = area->spacedata.first;
@@ -597,15 +615,15 @@ static void node_cursor(wmWindow *win, ScrArea *area, ARegion *region)
UI_view2d_region_to_view(&region->v2d,
win->eventstate->x - region->winrct.xmin,
win->eventstate->y - region->winrct.ymin,
- &snode->cursor[0],
- &snode->cursor[1]);
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
- /* here snode->cursor is used to detect the node edge for sizing */
- node_set_cursor(win, snode, snode->cursor);
+ /* here snode->runtime->cursor is used to detect the node edge for sizing */
+ node_set_cursor(win, snode, snode->runtime->cursor);
- /* XXX snode->cursor is in placing new nodes space */
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ /* XXX snode->runtime->cursor is in placing new nodes space */
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
}
/* Initialize main region, setting handlers. */
@@ -645,7 +663,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C),
/* rule might not work? */
return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
}
- return WM_drag_get_local_ID(drag, ID_IM) != NULL;
+ return WM_drag_is_ID_type(drag, ID_IM);
}
static bool node_mask_drop_poll(bContext *UNUSED(C),
@@ -653,19 +671,19 @@ static bool node_mask_drop_poll(bContext *UNUSED(C),
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
{
- return WM_drag_get_local_ID(drag, ID_MSK) != NULL;
+ return WM_drag_is_ID_type(drag, ID_MSK);
}
static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_get_local_ID(drag, 0);
+ ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_get_local_ID(drag, 0);
+ ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
@@ -703,12 +721,10 @@ static void node_header_region_draw(const bContext *C, ARegion *region)
}
/* used for header + main region */
-static void node_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void node_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
wmGizmoMap *gzmap = region->gizmo_map;
/* context changes */
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index e0262371559..d54265aa292 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
../../makesrna
../../sequencer
../../windowmanager
+ ../../../../intern/clog
../../../../intern/glew-mx
../../../../intern/guardedalloc
)
diff --git a/source/blender/editors/space_outliner/outliner_context.c b/source/blender/editors/space_outliner/outliner_context.c
index a314a640e42..e2b3b79e027 100644
--- a/source/blender/editors/space_outliner/outliner_context.c
+++ b/source/blender/editors/space_outliner/outliner_context.c
@@ -27,8 +27,6 @@
#include "DNA_space_types.h"
-#include "RNA_access.h"
-
#include "outliner_intern.h"
static void outliner_context_selected_ids_recursive(const ListBase *subtree,
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index ab515c0c3a8..70aeef76234 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -140,6 +140,11 @@ static TreeElement *outliner_drop_insert_find(bContext *C,
TreeElement *te_hovered;
float view_mval[2];
+ /* Empty tree, e.g. while filtered. */
+ if (BLI_listbase_is_empty(&space_outliner->tree)) {
+ return NULL;
+ }
+
UI_view2d_region_to_view(
&region->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
te_hovered = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_mval[1]);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 8104c1e0d58..76c710b3db1 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -314,7 +314,7 @@ static void outliner_object_set_flag_recursive_fn(bContext *C,
/**
* Object properties.
- * */
+ */
static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Object *ob = poin;
@@ -324,7 +324,7 @@ static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void
/**
* Base properties.
- * */
+ */
static void outliner__base_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Base *base = poin;
@@ -697,13 +697,13 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname)
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
break;
}
default:
- WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
break;
}
+ WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
+
/* Check the library target exists */
if (te->idcode == ID_LI) {
Library *lib = (Library *)tselem->id;
@@ -2287,12 +2287,6 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case TSE_R_LAYER:
data.icon = ICON_RENDER_RESULT;
break;
- case TSE_LINKED_LAMP:
- data.icon = ICON_LIGHT_DATA;
- break;
- case TSE_LINKED_MAT:
- data.icon = ICON_MATERIAL_DATA;
- break;
case TSE_POSEGRP_BASE:
case TSE_POSEGRP:
data.icon = ICON_GROUP_BONE;
@@ -2695,13 +2689,16 @@ static void outliner_draw_iconrow_number(const uiFontStyle *fstyle,
float offset_x = (float)offsx + UI_UNIT_X * 0.35f;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- offset_x + ufac,
- (float)ys - UI_UNIT_Y * 0.2f + ufac,
- offset_x + UI_UNIT_X - ufac,
- (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 2.0f - ufac,
- color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = offset_x + ufac,
+ .xmax = offset_x + UI_UNIT_X - ufac,
+ .ymin = (float)ys - UI_UNIT_Y * 0.2f + ufac,
+ .ymax = (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac,
+ },
+ true,
+ (float)UI_UNIT_Y / 2.0f - ufac,
+ color);
/* Now the numbers. */
uchar text_col[4];
@@ -2751,8 +2748,26 @@ static void outliner_draw_active_indicator(const float minx,
const float radius = UI_UNIT_Y / 4.0f;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true, minx, miny + ufac, maxx, maxy - ufac, radius, icon_color);
- UI_draw_roundbox_aa(false, minx, miny + ufac, maxx, maxy - ufac, radius, icon_border);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = minx,
+ .xmax = maxx,
+ .ymin = miny + ufac,
+ .ymax = maxy - ufac,
+ },
+ true,
+ radius,
+ icon_color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = minx,
+ .xmax = maxx,
+ .ymin = miny + ufac,
+ .ymax = maxy - ufac,
+ },
+ false,
+ radius,
+ icon_border);
GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */
}
@@ -3038,7 +3053,7 @@ static void outliner_draw_tree_element(bContext *C,
}
else {
active = tree_element_type_active(C, tvc, space_outliner, te, tselem, OL_SETSEL_NONE, false);
- /* active collection*/
+ /* Active collection. */
}
/* active circle */
@@ -3058,7 +3073,7 @@ static void outliner_draw_tree_element(bContext *C,
}
else if (te->subtree.first || (tselem->type == 0 && te->idcode == ID_SCE) ||
(te->flag & TE_LAZY_CLOSED)) {
- /* open/close icon, only when sublevels, except for scene */
+ /* Open/close icon, only when sub-levels, except for scene. */
int icon_x = startx;
/* Icons a bit higher. */
@@ -3496,7 +3511,7 @@ static void outliner_draw_tree(bContext *C,
GPU_scissor(0, 0, mask_x, region->winy);
}
- /* Draw hierarhcy lines for collections and object children. */
+ /* Draw hierarchy lines for collections and object children. */
starty = (int)region->v2d.tot.ymax - OL_Y_OFFSET;
startx = mode_column_offset + UI_UNIT_X / 2 - (U.pixelsize + 1) / 2;
outliner_draw_hierarchy_lines(space_outliner, &space_outliner->tree, startx, &starty);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index acda5ae82f0..7e5b0c90714 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -21,22 +21,9 @@
* \ingroup spoutliner
*/
-#include "MEM_guardedalloc.h"
-
-#include "DNA_collection_types.h"
-
-#include "BLT_translation.h"
-
-#include "RNA_access.h"
-
-#include "UI_interface.h"
-#include "UI_view2d.h"
-
#include "WM_api.h"
-#include "WM_types.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "outliner_intern.h"
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 600047c4b11..4a58736966c 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -927,25 +927,6 @@ static eOLDrawState tree_element_active_sequence_dup(Scene *scene,
return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_keymap_item(bContext *UNUSED(C),
- Scene *UNUSED(scene),
- ViewLayer *UNUSED(sl),
- TreeElement *te,
- TreeStoreElem *UNUSED(tselem),
- const eOLSetState set)
-{
- wmKeyMapItem *kmi = te->directdata;
-
- if (set == OL_SETSEL_NONE) {
- if (kmi->flag & KMI_INACTIVE) {
- return OL_DRAWSEL_NONE;
- }
- return OL_DRAWSEL_NORMAL;
- }
- kmi->flag ^= KMI_INACTIVE;
- return OL_DRAWSEL_NONE;
-}
-
static eOLDrawState tree_element_active_master_collection(bContext *C,
TreeElement *UNUSED(te),
const eOLSetState set)
@@ -1071,8 +1052,6 @@ eOLDrawState tree_element_type_active(bContext *C,
return tree_element_active_sequence(C, tvc->scene, te, tselem, set);
case TSE_SEQUENCE_DUP:
return tree_element_active_sequence_dup(tvc->scene, te, tselem, set);
- case TSE_KEYMAP_ITEM:
- return tree_element_active_keymap_item(C, tvc->scene, tvc->view_layer, te, tselem, set);
case TSE_GP_LAYER:
return tree_element_active_gplayer(C, tvc->scene, te, tselem, set);
break;
@@ -1543,7 +1522,7 @@ static bool outliner_is_co_within_active_mode_column(bContext *C,
* Action to run when clicking in the outliner,
*
* May expend/collapse branches or activate items.
- * */
+ */
static int outliner_item_do_activate_from_cursor(bContext *C,
const int mval[2],
const bool extend,
diff --git a/source/blender/editors/space_outliner/outliner_sync.c b/source/blender/editors/space_outliner/outliner_sync.c
index 0b2d1ce34ec..8bd5e3a130a 100644
--- a/source/blender/editors/space_outliner/outliner_sync.c
+++ b/source/blender/editors/space_outliner/outliner_sync.c
@@ -38,7 +38,6 @@
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_main.h"
-#include "BKE_object.h"
#include "DEG_depsgraph.h"
@@ -378,7 +377,7 @@ void ED_outliner_select_sync_from_outliner(bContext *C, SpaceOutliner *space_out
selected_items_free(&selected_items);
- /* Tag for updates and clear dirty flag toprevent a sync to the outliner on draw */
+ /* Tag for updates and clear dirty flag to prevent a sync to the outliner on draw. */
if (sync_types.object) {
space_outliner->sync_select_dirty &= ~WM_OUTLINER_SYNC_SELECT_FROM_OBJECT;
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
@@ -545,7 +544,7 @@ static void get_sync_select_active_data(const bContext *C, SyncSelectActiveData
active_data->sequence = SEQ_select_active_get(scene);
}
-/* If outliner is dirty sync selection from view layer and sequwncer */
+/* If outliner is dirty sync selection from view layer and sequencer. */
void outliner_sync_selection(const bContext *C, SpaceOutliner *space_outliner)
{
/* Set which types of data to sync from sync dirty flag and outliner display mode */
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 2a2803c58dd..8b522d41af8 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -23,6 +23,8 @@
#include "MEM_guardedalloc.h"
+#include "CLG_log.h"
+
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_collection_types.h"
@@ -92,6 +94,8 @@
#include "outliner_intern.h"
+static CLG_LogRef LOG = {"ed.outliner.tools"};
+
/* -------------------------------------------------------------------- */
/** \name ID/Library/Data Set/Un-link Utilities
* \{ */
@@ -790,7 +794,7 @@ static void id_override_library_create_fn(bContext *C,
id_root->tag |= LIB_TAG_DOIT;
- /* For now, remapp all local usages of linked ID to local override one here. */
+ /* For now, remap all local usages of linked ID to local override one here. */
ID *id_iter;
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
if (ID_IS_LINKED(id_iter)) {
@@ -824,6 +828,9 @@ static void id_override_library_create_fn(bContext *C,
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
}
}
+ else {
+ CLOG_WARN(&LOG, "Could not create library override for data block '%s'", id_root->name);
+ }
}
static void id_override_library_reset_fn(bContext *C,
@@ -852,6 +859,9 @@ static void id_override_library_reset_fn(bContext *C,
WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
+ else {
+ CLOG_WARN(&LOG, "Could not reset library override of data block '%s'", id_root->name);
+ }
}
static void id_override_library_resync_fn(bContext *C,
@@ -883,6 +893,9 @@ static void id_override_library_resync_fn(bContext *C,
BKE_lib_override_library_resync(bmain, scene, CTX_data_view_layer(C), id_root);
}
+ else {
+ CLOG_WARN(&LOG, "Could not resync library override of data block '%s'", id_root->name);
+ }
}
static void id_override_library_delete_fn(bContext *C,
@@ -914,6 +927,9 @@ static void id_override_library_delete_fn(bContext *C,
BKE_lib_override_library_delete(bmain, id_root);
}
+ else {
+ CLOG_WARN(&LOG, "Could not delete library override of data block '%s'", id_root->name);
+ }
}
static void id_fake_user_set_fn(bContext *UNUSED(C),
@@ -1789,21 +1805,44 @@ static bool outliner_id_operation_item_poll(bContext *C,
const int enum_value)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
+ TreeElement *te = get_target_element(space_outliner);
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (!TSE_IS_REAL_ID(tselem)) {
+ return false;
+ }
+
+ Object *ob = NULL;
+ if (GS(tselem->id->name) == ID_OB) {
+ ob = (Object *)tselem->id;
+ }
switch (enum_value) {
case OUTLINER_IDOP_MARK_ASSET:
case OUTLINER_IDOP_CLEAR_ASSET:
return U.experimental.use_asset_browser;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE:
+ if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id)) {
+ return true;
+ }
+ return false;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY:
- return true;
+ if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id) || (ID_IS_LINKED(tselem->id))) {
+ return true;
+ }
+ return false;
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_PROXY_CONVERT:
+ if (ob != NULL && ob->proxy != NULL) {
+ return true;
+ }
+ return false;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET:
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY:
- return true;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY:
- return true;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY:
- return true;
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id)) {
+ return true;
+ }
+ return false;
case OUTLINER_IDOP_SINGLE:
if (!space_outliner || ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) {
return true;
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index acfeccca175..f94f19246fa 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -167,8 +167,6 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
static void check_persistent(
SpaceOutliner *space_outliner, TreeElement *te, ID *id, short type, short nr)
{
- TreeStoreElem *tselem;
-
if (space_outliner->treestore == NULL) {
/* if treestore was not created in readfile.c, create it here */
space_outliner->treestore = BLI_mempool_create(
@@ -181,7 +179,8 @@ static void check_persistent(
/* find any unused tree element in treestore and mark it as used
* (note that there may be multiple unused elements in case of linked objects) */
- tselem = BKE_outliner_treehash_lookup_unused(space_outliner->runtime->treehash, type, nr, id);
+ TreeStoreElem *tselem = BKE_outliner_treehash_lookup_unused(
+ space_outliner->runtime->treehash, type, nr, id);
if (tselem) {
te->store_elem = tselem;
tselem->used = 1;
@@ -204,8 +203,7 @@ static void check_persistent(
void outliner_free_tree(ListBase *tree)
{
- for (TreeElement *element = tree->first, *element_next; element; element = element_next) {
- element_next = element->next;
+ LISTBASE_FOREACH_MUTABLE (TreeElement *, element, tree) {
outliner_free_tree_element(element, tree);
}
}
@@ -271,8 +269,8 @@ static void outliner_add_bone(SpaceOutliner *space_outliner,
te->name = curBone->name;
te->directdata = curBone;
- for (curBone = curBone->childbase.first; curBone; curBone = curBone->next) {
- outliner_add_bone(space_outliner, &te->subtree, id, curBone, te, a);
+ LISTBASE_FOREACH (Bone *, child_bone, &curBone->childbase) {
+ outliner_add_bone(space_outliner, &te->subtree, id, child_bone, te, a);
}
}
@@ -381,35 +379,30 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (ob->pose) {
bArmature *arm = ob->data;
- bPoseChannel *pchan;
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_POSE_BASE, 0);
-
tenla->name = IFACE_("Pose");
/* channels undefined in editmode, but we want the 'tenla' pose icon itself */
if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) {
- TreeElement *ten;
- int a = 0, const_index = 1000; /* ensure unique id for bone constraints */
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, a++) {
- ten = outliner_add_element(
+ int const_index = 1000; /* ensure unique id for bone constraints */
+ int a;
+ LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob->pose->chanbase, a) {
+ TreeElement *ten = outliner_add_element(
space_outliner, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
ten->name = pchan->name;
ten->directdata = pchan;
pchan->temp = (void *)ten;
- if (pchan->constraints.first) {
+ if (!BLI_listbase_is_empty(&pchan->constraints)) {
/* Object *target; */
- bConstraint *con;
- TreeElement *ten1;
TreeElement *tenla1 = outliner_add_element(
space_outliner, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
+ tenla1->name = IFACE_("Constraints");
/* char *str; */
- tenla1->name = IFACE_("Constraints");
- for (con = pchan->constraints.first; con; con = con->next, const_index++) {
- ten1 = outliner_add_element(
+ LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
+ TreeElement *ten1 = outliner_add_element(
space_outliner, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
#if 0 /* disabled as it needs to be reworked for recoded constraints system */
target = get_constraint_target(con, &str);
@@ -427,15 +420,16 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
ten1->directdata = con;
/* possible add all other types links? */
}
+ const_index++;
}
}
/* make hierarchy */
- ten = tenla->subtree.first;
+ TreeElement *ten = tenla->subtree.first;
while (ten) {
TreeElement *nten = ten->next, *par;
tselem = TREESTORE(ten);
if (tselem->type == TSE_POSE_CHANNEL) {
- pchan = (bPoseChannel *)ten->directdata;
+ bPoseChannel *pchan = (bPoseChannel *)ten->directdata;
if (pchan->parent) {
BLI_remlink(&tenla->subtree, ten);
par = (TreeElement *)pchan->parent->temp;
@@ -448,17 +442,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
/* Pose Groups */
- if (ob->pose->agroups.first) {
- bActionGroup *agrp;
+ if (!BLI_listbase_is_empty(&ob->pose->agroups)) {
TreeElement *ten_bonegrp = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
- int a = 0;
-
ten_bonegrp->name = IFACE_("Bone Groups");
- for (agrp = ob->pose->agroups.first; agrp; agrp = agrp->next, a++) {
- TreeElement *ten;
- ten = outliner_add_element(
- space_outliner, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a);
+
+ int index;
+ LISTBASE_FOREACH_INDEX (bActionGroup *, agrp, &ob->pose->agroups, index) {
+ TreeElement *ten = outliner_add_element(
+ space_outliner, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, index);
ten->name = agrp->name;
ten->directdata = agrp;
}
@@ -469,18 +461,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
outliner_add_element(space_outliner, &te->subtree, ob->mat[a], te, 0, a);
}
- if (ob->constraints.first) {
- /* Object *target; */
- bConstraint *con;
- TreeElement *ten;
+ if (!BLI_listbase_is_empty(&ob->constraints)) {
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
- /* char *str; */
- int a;
-
tenla->name = IFACE_("Constraints");
- for (con = ob->constraints.first, a = 0; con; con = con->next, a++) {
- ten = outliner_add_element(space_outliner, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
+
+ int index;
+ LISTBASE_FOREACH_INDEX (bConstraint *, con, &ob->constraints, index) {
+ TreeElement *ten = outliner_add_element(
+ space_outliner, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, index);
#if 0 /* disabled due to constraints system targets recode... code here needs review */
target = get_constraint_target(con, &str);
if (str && str[0]) {
@@ -499,14 +488,13 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
}
- if (ob->modifiers.first) {
- ModifierData *md;
+ if (!BLI_listbase_is_empty(&ob->modifiers)) {
TreeElement *ten_mod = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
- int index;
-
ten_mod->name = IFACE_("Modifiers");
- for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) {
+
+ int index;
+ LISTBASE_FOREACH_INDEX (ModifierData *, md, &ob->modifiers, index) {
TreeElement *ten = outliner_add_element(
space_outliner, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
ten->name = md->name;
@@ -559,8 +547,8 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (!BLI_listbase_is_empty(&ob->greasepencil_modifiers)) {
TreeElement *ten_mod = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
-
ten_mod->name = IFACE_("Modifiers");
+
int index;
LISTBASE_FOREACH_INDEX (GpencilModifierData *, md, &ob->greasepencil_modifiers, index) {
TreeElement *ten = outliner_add_element(
@@ -599,8 +587,8 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (!BLI_listbase_is_empty(&ob->shader_fx)) {
TreeElement *ten_fx = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_GPENCIL_EFFECT_BASE, 0);
-
ten_fx->name = IFACE_("Effects");
+
int index;
LISTBASE_FOREACH_INDEX (ShaderFxData *, fx, &ob->shader_fx, index) {
TreeElement *ten = outliner_add_element(
@@ -620,16 +608,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
/* vertex groups */
- if (ob->defbase.first) {
- bDeformGroup *defgroup;
- TreeElement *ten;
+ if (!BLI_listbase_is_empty(&ob->defbase)) {
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
- int a;
-
tenla->name = IFACE_("Vertex Groups");
- for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) {
- ten = outliner_add_element(space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
+
+ int index;
+ LISTBASE_FOREACH_INDEX (bDeformGroup *, defgroup, &ob->defbase, index) {
+ TreeElement *ten = outliner_add_element(
+ space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, index);
ten->name = defgroup->name;
ten->directdata = defgroup;
}
@@ -694,14 +681,13 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_ME: {
Mesh *me = (Mesh *)id;
- int a;
if (outliner_animdata_test(me->adt)) {
outliner_add_element(space_outliner, &te->subtree, me, te, TSE_ANIM_DATA, 0);
}
outliner_add_element(space_outliner, &te->subtree, me->key, te, 0, 0);
- for (a = 0; a < me->totcol; a++) {
+ for (int a = 0; a < me->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, me->mat[a], te, 0, a);
}
/* could do tfaces with image links, but the images are not grouped nicely.
@@ -710,33 +696,30 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CU: {
Curve *cu = (Curve *)id;
- int a;
if (outliner_animdata_test(cu->adt)) {
outliner_add_element(space_outliner, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
}
- for (a = 0; a < cu->totcol; a++) {
+ for (int a = 0; a < cu->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, cu->mat[a], te, 0, a);
}
break;
}
case ID_MB: {
MetaBall *mb = (MetaBall *)id;
- int a;
if (outliner_animdata_test(mb->adt)) {
outliner_add_element(space_outliner, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
}
- for (a = 0; a < mb->totcol; a++) {
+ for (int a = 0; a < mb->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, mb->mat[a], te, 0, a);
}
break;
}
case ID_MA: {
Material *ma = (Material *)id;
-
if (outliner_animdata_test(ma->adt)) {
outliner_add_element(space_outliner, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
}
@@ -744,7 +727,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_TE: {
Tex *tex = (Tex *)id;
-
if (outliner_animdata_test(tex->adt)) {
outliner_add_element(space_outliner, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
}
@@ -753,7 +735,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CA: {
Camera *ca = (Camera *)id;
-
if (outliner_animdata_test(ca->adt)) {
outliner_add_element(space_outliner, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
}
@@ -761,7 +742,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CF: {
CacheFile *cache_file = (CacheFile *)id;
-
if (outliner_animdata_test(cache_file->adt)) {
outliner_add_element(space_outliner, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
}
@@ -770,7 +750,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LA: {
Light *la = (Light *)id;
-
if (outliner_animdata_test(la->adt)) {
outliner_add_element(space_outliner, &te->subtree, la, te, TSE_ANIM_DATA, 0);
}
@@ -778,7 +757,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_SPK: {
Speaker *spk = (Speaker *)id;
-
if (outliner_animdata_test(spk->adt)) {
outliner_add_element(space_outliner, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
}
@@ -786,7 +764,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LP: {
LightProbe *prb = (LightProbe *)id;
-
if (outliner_animdata_test(prb->adt)) {
outliner_add_element(space_outliner, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
}
@@ -794,7 +771,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_WO: {
World *wrld = (World *)id;
-
if (outliner_animdata_test(wrld->adt)) {
outliner_add_element(space_outliner, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
}
@@ -802,7 +778,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_KE: {
Key *key = (Key *)id;
-
if (outliner_animdata_test(key->adt)) {
outliner_add_element(space_outliner, &te->subtree, key, te, TSE_ANIM_DATA, 0);
}
@@ -815,27 +790,25 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_AR: {
bArmature *arm = (bArmature *)id;
- int a = 0;
if (outliner_animdata_test(arm->adt)) {
outliner_add_element(space_outliner, &te->subtree, arm, te, TSE_ANIM_DATA, 0);
}
if (arm->edbo) {
- EditBone *ebone;
- TreeElement *ten;
-
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next, a++) {
- ten = outliner_add_element(space_outliner, &te->subtree, id, te, TSE_EBONE, a);
+ int a = 0;
+ LISTBASE_FOREACH_INDEX (EditBone *, ebone, arm->edbo, a) {
+ TreeElement *ten = outliner_add_element(
+ space_outliner, &te->subtree, id, te, TSE_EBONE, a);
ten->directdata = ebone;
ten->name = ebone->name;
ebone->temp.p = ten;
}
/* make hierarchy */
- ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL;
+ TreeElement *ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL;
while (ten) {
TreeElement *nten = ten->next, *par;
- ebone = (EditBone *)ten->directdata;
+ EditBone *ebone = (EditBone *)ten->directdata;
if (ebone->parent) {
BLI_remlink(&te->subtree, ten);
par = ebone->parent->temp.p;
@@ -852,9 +825,9 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
/* pass */
}
else {
- Bone *curBone;
- for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
- outliner_add_bone(space_outliner, &te->subtree, id, curBone, te, &a);
+ int a = 0;
+ LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
+ outliner_add_bone(space_outliner, &te->subtree, id, bone, te, &a);
}
}
}
@@ -862,13 +835,12 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LS: {
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
- int a;
if (outliner_animdata_test(linestyle->adt)) {
outliner_add_element(space_outliner, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
}
- for (a = 0; a < MAX_MTEX; a++) {
+ for (int a = 0; a < MAX_MTEX; a++) {
if (linestyle->mtex[a]) {
outliner_add_element(space_outliner, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
}
@@ -877,17 +849,16 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_GD: {
bGPdata *gpd = (bGPdata *)id;
- bGPDlayer *gpl;
- int a = 0;
if (outliner_animdata_test(gpd->adt)) {
outliner_add_element(space_outliner, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
}
/* TODO: base element for layers? */
- for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
- outliner_add_element(space_outliner, &te->subtree, gpl, te, TSE_GP_LAYER, a);
- a++;
+ int index = 0;
+ LISTBASE_FOREACH_BACKWARD (bGPDlayer *, gpl, &gpd->layers) {
+ outliner_add_element(space_outliner, &te->subtree, gpl, te, TSE_GP_LAYER, index);
+ index++;
}
break;
}
@@ -957,8 +928,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
short type,
short index)
{
- TreeElement *te;
- TreeStoreElem *tselem;
ID *id = idv;
if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
@@ -985,12 +954,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
BLI_assert(TREESTORE_ID_TYPE(id));
}
- te = MEM_callocN(sizeof(TreeElement), "tree elem");
+ TreeElement *te = MEM_callocN(sizeof(TreeElement), __func__);
/* add to the visual tree */
BLI_addtail(lb, te);
/* add to the storage */
check_persistent(space_outliner, te, id, type, index);
- tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
/* if we are searching for something expand to see child elements */
if (SEARCHING_OUTLINER(space_outliner)) {
@@ -1022,9 +991,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
else if (type == TSE_ID_BASE) {
/* pass */
}
- else if (ELEM(type, TSE_KEYMAP, TSE_KEYMAP_ITEM)) {
- /* pass */
- }
else {
/* Other cases must be caught above. */
BLI_assert(TSE_IS_REAL_ID(tselem));
@@ -1062,7 +1028,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
else if (type == TSE_SEQUENCE) {
Sequence *seq = (Sequence *)idv;
- Sequence *p;
/*
* The idcode is a little hack, but the outliner
@@ -1081,10 +1046,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
*/
if (seq->type == SEQ_TYPE_META) {
- p = seq->seqbase.first;
- while (p) {
+ LISTBASE_FOREACH (Sequence *, p, &seq->seqbase) {
outliner_add_element(space_outliner, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
- p = p->next;
}
}
else {
@@ -1112,17 +1075,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->name = seq->strip->stripdata->name;
}
else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
- PointerRNA pptr, propptr, *ptr = (PointerRNA *)idv;
- PropertyRNA *prop, *iterprop;
- PropertyType proptype;
+ PointerRNA *ptr = (PointerRNA *)idv;
/* Don't display arrays larger, weak but index is stored as a short,
* also the outliner isn't intended for editing such large data-sets. */
BLI_STATIC_ASSERT(sizeof(te->index) == 2, "Index is no longer short!")
const int tot_limit = SHRT_MAX;
- int a, tot;
-
/* we do lazy build, for speed and to avoid infinite recursion */
if (ptr->data == NULL) {
@@ -1144,8 +1103,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
tselem->flag &= ~TSE_CHILDSEARCH;
}
- iterprop = RNA_struct_iterator_property(ptr->type);
- tot = RNA_property_collection_length(ptr, iterprop);
+ PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
+ int tot = RNA_property_collection_length(ptr, iterprop);
CLAMP_MAX(tot, tot_limit);
/* auto open these cases */
@@ -1156,7 +1115,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
if (TSELEM_OPEN(tselem, space_outliner)) {
- for (a = 0; a < tot; a++) {
+ for (int a = 0; a < tot; a++) {
+ PointerRNA propptr;
RNA_property_collection_lookup_int(ptr, iterprop, a, &propptr);
if (!(RNA_property_flag(propptr.data) & PROP_HIDDEN)) {
outliner_add_element(
@@ -1172,11 +1132,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
else if (type == TSE_RNA_PROPERTY) {
/* property */
- iterprop = RNA_struct_iterator_property(ptr->type);
+ PointerRNA propptr;
+ PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr);
- prop = propptr.data;
- proptype = RNA_property_type(prop);
+ PropertyRNA *prop = propptr.data;
+ PropertyType proptype = RNA_property_type(prop);
te->name = RNA_property_ui_name(prop);
te->directdata = prop;
@@ -1188,7 +1149,7 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
if (proptype == PROP_POINTER) {
- pptr = RNA_property_pointer_get(ptr, prop);
+ PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
if (pptr.data) {
if (TSELEM_OPEN(tselem, space_outliner)) {
@@ -1201,11 +1162,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (proptype == PROP_COLLECTION) {
- tot = RNA_property_collection_length(ptr, prop);
+ int tot = RNA_property_collection_length(ptr, prop);
CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, space_outliner)) {
- for (a = 0; a < tot; a++) {
+ for (int a = 0; a < tot; a++) {
+ PointerRNA pptr;
RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
outliner_add_element(
space_outliner, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a);
@@ -1216,11 +1178,11 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
- tot = RNA_property_array_length(ptr, prop);
+ int tot = RNA_property_array_length(ptr, prop);
CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, space_outliner)) {
- for (a = 0; a < tot; a++) {
+ for (int a = 0; a < tot; a++) {
outliner_add_element(
space_outliner, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a);
}
@@ -1231,15 +1193,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (type == TSE_RNA_ARRAY_ELEM) {
- char c;
-
- prop = parent->directdata;
+ PropertyRNA *prop = parent->directdata;
te->directdata = prop;
te->rnaptr = *ptr;
te->index = index;
- c = RNA_property_array_item_char(prop, index);
+ char c = RNA_property_array_item_char(prop, index);
te->name = MEM_callocN(sizeof(char[20]), "OutlinerRNAArrayName");
if (c) {
@@ -1251,52 +1211,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->flag |= TE_FREE_NAME;
}
}
- else if (type == TSE_KEYMAP) {
- wmKeyMap *km = (wmKeyMap *)idv;
- wmKeyMapItem *kmi;
- char opname[OP_MAX_TYPENAME];
-
- te->directdata = idv;
- te->name = km->idname;
-
- if (TSELEM_OPEN(tselem, space_outliner)) {
- int a = 0;
-
- for (kmi = km->items.first; kmi; kmi = kmi->next, a++) {
- const char *key = WM_key_event_string(kmi->type, false);
-
- if (key[0]) {
- wmOperatorType *ot = NULL;
-
- if (kmi->propvalue) {
- /* pass */
- }
- else {
- ot = WM_operatortype_find(kmi->idname, 0);
- }
-
- if (ot || kmi->propvalue) {
- TreeElement *ten = outliner_add_element(
- space_outliner, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
-
- ten->directdata = kmi;
-
- if (kmi->propvalue) {
- ten->name = IFACE_("Modal map, not yet");
- }
- else {
- WM_operator_py_idname(opname, ot->idname);
- ten->name = BLI_strdup(opname);
- ten->flag |= TE_FREE_NAME;
- }
- }
- }
- }
- }
- else {
- te->flag |= TE_LAZY_CLOSED;
- }
- }
return te;
}
@@ -1344,21 +1258,18 @@ static TreeElement *outliner_add_collection_recursive(SpaceOutliner *space_outli
/* make sure elements are correctly nested */
void outliner_make_object_parent_hierarchy(ListBase *lb)
{
- TreeElement *te, *ten, *tep;
- TreeStoreElem *tselem;
-
/* build hierarchy */
/* XXX also, set extents here... */
- te = lb->first;
+ TreeElement *te = lb->first;
while (te) {
- ten = te->next;
- tselem = TREESTORE(te);
+ TreeElement *ten = te->next;
+ TreeStoreElem *tselem = TREESTORE(te);
if (tselem->type == 0 && te->idcode == ID_OB) {
Object *ob = (Object *)tselem->id;
if (ob->parent && ob->parent->id.newid) {
BLI_remlink(lb, te);
- tep = (TreeElement *)ob->parent->id.newid;
+ TreeElement *tep = (TreeElement *)ob->parent->id.newid;
BLI_addtail(&tep->subtree, te);
te->parent = tep;
}
@@ -1380,10 +1291,9 @@ typedef struct tTreeSort {
static int treesort_alpha_ob(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
- int comp;
/* first put objects last (hierarchy) */
- comp = (x1->idcode == ID_OB);
+ int comp = (x1->idcode == ID_OB);
if (x2->idcode == ID_OB) {
comp += 2;
}
@@ -1432,9 +1342,8 @@ static int treesort_child_not_in_collection(const void *v1, const void *v2)
static int treesort_alpha(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
- int comp;
- comp = BLI_strcasecmp_natural(x1->name, x2->name);
+ int comp = BLI_strcasecmp_natural(x1->name, x2->name);
if (comp > 0) {
return 1;
@@ -1489,14 +1398,11 @@ static int treesort_obtype_alpha(const void *v1, const void *v2)
/* sort happens on each subtree individual */
static void outliner_sort(ListBase *lb)
{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- te = lb->last;
+ TreeElement *te = lb->last;
if (te == NULL) {
return;
}
- tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
/* sorting rules; only object lists, ID lists, or deformgroups */
if (ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) ||
@@ -1558,14 +1464,11 @@ static void outliner_sort(ListBase *lb)
static void outliner_collections_children_sort(ListBase *lb)
{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- te = lb->last;
+ TreeElement *te = lb->last;
if (te == NULL) {
return;
}
- tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
/* Sorting rules: only object lists. */
if (tselem->type == 0 && te->idcode == ID_OB) {
@@ -1687,8 +1590,7 @@ static TreeElement *outliner_find_first_desired_element_at_y(const SpaceOutliner
const float view_co,
const float view_co_limit)
{
- TreeElement *te, *te_sub;
- te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_co);
+ TreeElement *te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_co);
bool (*callback_test)(TreeElement *);
if ((space_outliner->outlinevis == SO_VIEW_LAYER) &&
@@ -1700,7 +1602,7 @@ static TreeElement *outliner_find_first_desired_element_at_y(const SpaceOutliner
}
while (te != NULL) {
- te_sub = outliner_find_first_desired_element_at_y_recursive(
+ TreeElement *te_sub = outliner_find_first_desired_element_at_y_recursive(
space_outliner, te, view_co_limit, callback_test);
if (te_sub != NULL) {
/* Skip the element if it was not visible to start with. */
@@ -1742,12 +1644,12 @@ static void outliner_store_scrolling_position(SpaceOutliner *space_outliner,
ARegion *region,
OutlinerTreeElementFocus *focus)
{
- TreeElement *te;
float limit = region->v2d.cur.ymin;
outliner_set_coordinates(region, space_outliner);
- te = outliner_find_first_desired_element_at_y(space_outliner, region->v2d.cur.ymax, limit);
+ TreeElement *te = outliner_find_first_desired_element_at_y(
+ space_outliner, region->v2d.cur.ymax, limit);
if (te != NULL) {
focus->tselem = TREESTORE(te);
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index e0d63dfcf81..92178cfdfc9 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -169,7 +169,7 @@ TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *space_outliner,
return te;
}
-/* Find specific item from the treestore */
+/* Find specific item from the trees-tore. */
TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem)
{
LISTBASE_FOREACH (TreeElement *, te, lb) {
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 6c9d4433abd..87f81a2cc0e 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -31,9 +31,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_layer.h"
#include "BKE_outliner_treehash.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
#include "ED_screen.h"
@@ -51,7 +49,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_framebuffer.h"
#include "outliner_intern.h"
#include "tree/tree_display.h"
@@ -102,12 +99,11 @@ static void outliner_main_region_free(ARegion *UNUSED(region))
{
}
-static void outliner_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void outliner_main_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
SpaceOutliner *space_outliner = area->spacedata.first;
/* context changes */
@@ -264,15 +260,13 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void outliner_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void outliner_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceOutliner *space_outliner = area->spacedata.first;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -301,12 +295,11 @@ static void outliner_header_region_free(ARegion *UNUSED(region))
{
}
-static void outliner_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void outliner_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -332,7 +325,7 @@ static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUS
space_outliner = MEM_callocN(sizeof(SpaceOutliner), "initoutliner");
space_outliner->spacetype = SPACE_OUTLINER;
space_outliner->filter_id_type = ID_GR;
- space_outliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_HIDE;
+ space_outliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_HIDE | SO_RESTRICT_RENDER;
space_outliner->outlinevis = SO_VIEW_LAYER;
space_outliner->sync_select_dirty |= WM_OUTLINER_SYNC_SELECT_FROM_ALL;
space_outliner->flag = SO_SYNC_SELECT | SO_MODE_COLUMN;
diff --git a/source/blender/editors/space_outliner/tree/tree_display.cc b/source/blender/editors/space_outliner/tree/tree_display.cc
index d2070fb9b1c..6632c057814 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display.cc
@@ -18,8 +18,6 @@
* \ingroup spoutliner
*/
-#include "BLI_listbase.h"
-
#include "DNA_listBase.h"
#include "tree_display.hh"
diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc
index ce2a8fa634d..27846614994 100644
--- a/source/blender/editors/space_outliner/tree/tree_element.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element.cc
@@ -20,8 +20,6 @@
#include "DNA_listBase.h"
-#include "../outliner_intern.h"
-
#include "tree_element_anim_data.hh"
#include "tree_element_driver_base.hh"
#include "tree_element_nla.hh"
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 3330ba14530..4ce0e454df8 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -36,7 +36,6 @@
#include "ED_space_api.h"
#include "WM_api.h"
-#include "WM_types.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -44,7 +43,6 @@
#ifdef WITH_PYTHON
#endif
-#include "GPU_framebuffer.h"
#include "script_intern.h" /* own include */
// static script_run_python(char *funcname, )
@@ -156,13 +154,8 @@ static void script_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void script_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void script_main_region_listener(const wmRegionListenerParams *UNUSED(params))
{
-/* context changes */
/* XXX - Todo, need the ScriptSpace accessible to get the python script to run. */
#if 0
BPY_run_script_space_listener()
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index f9076145f2f..e605cf4a889 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -66,8 +66,6 @@
#include "UI_interface.h"
-#include "BKE_sound.h"
-
#ifdef WITH_AUDASPACE
# include <AUD_Sequence.h>
#endif
@@ -1069,6 +1067,9 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
else if (seq->type == SEQ_TYPE_TEXT) {
seq->blend_mode = SEQ_TYPE_ALPHAOVER;
}
+ else if (SEQ_effect_get_num_inputs(seq->type) == 1) {
+ seq->blend_mode = seq1->blend_mode;
+ }
/* Set channel. If unset, use lowest free one above strips. */
if (!RNA_struct_property_is_set(op->ptr, "channel")) {
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index a8c13d63259..11614d94862 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -35,13 +35,9 @@
#include "BKE_global.h"
#include "BKE_screen.h"
-#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_sequencer.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 72c3e43185b..201df1ceed6 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1447,15 +1447,24 @@ static void sequencer_draw_borders_overlay(const SpaceSeq *sseq,
if (sseq->flag & SEQ_SHOW_SAFE_MARGINS) {
immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
- UI_draw_safe_areas(
- shdr_pos, x1, x2, y1, y2, scene->safe_areas.title, scene->safe_areas.action);
+ UI_draw_safe_areas(shdr_pos,
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
+ scene->safe_areas.title,
+ scene->safe_areas.action);
if (sseq->flag & SEQ_SHOW_SAFE_CENTER) {
UI_draw_safe_areas(shdr_pos,
- x1,
- x2,
- y1,
- y2,
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
scene->safe_areas.title_center,
scene->safe_areas.action_center);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 7474f8034de..608e220c582 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -28,7 +28,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_timecode.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index 7bfc8600544..48e6cfcdcd0 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -29,12 +29,7 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_markers.h"
-#include "ED_select_utils.h"
#include "ED_sequencer.h"
-#include "ED_transform.h" /* Transform keymap. */
-
-#include "SEQ_sequencer.h"
#include "sequencer_intern.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c
index b9698492aa5..24fa4ad7a17 100644
--- a/source/blender/editors/space_sequencer/sequencer_proxy.c
+++ b/source/blender/editors/space_sequencer/sequencer_proxy.c
@@ -25,7 +25,6 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
-#include "BLI_timecode.h"
#include "DNA_scene_types.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index f5707d1ea65..16768e09cb8 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -30,8 +30,6 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "atomic_ops.h"
-
#include "sequencer_intern.h"
/* XXX, why is this function better than BLI_math version?
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 3b476fefe47..ffcb3d35d5a 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -26,6 +26,7 @@
#include <string.h>
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -771,69 +772,83 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
* \{ */
/* Run recursively to select linked. */
-static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool linked)
+static bool select_linked_internal(Scene *scene)
{
Editing *ed = SEQ_editing_get(scene, false);
- Sequence *seq, *neighbor;
- bool changed = false;
- int isel;
if (ed == NULL) {
- return changed;
+ return false;
}
- if (sel) {
- sel = SELECT;
- isel = 0;
+ bool changed = false;
+
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
+ if ((seq->flag & SELECT) != 0) {
+ continue;
+ }
+ /* Only get unselected neighbors. */
+ Sequence *neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, 0);
+ if (neighbor) {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ changed = true;
+ }
+ neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, 0);
+ if (neighbor) {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ changed = true;
+ }
}
- else {
- sel = 0;
- isel = SELECT;
+
+ return changed;
+}
+
+/* Select only one linked strip on each side. */
+static bool select_more_less_seq__internal(Scene *scene, bool select_more)
+{
+ Editing *ed = SEQ_editing_get(scene, false);
+
+ if (ed == NULL) {
+ return false;
}
- if (!linked) {
- /* If not linked we only want to touch each seq once, newseq. */
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- seq->tmp = NULL;
+ GSet *neighbors = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "Linked strips");
+ const int neighbor_selection_filter = select_more ? 0 : SELECT;
+ const int selection_filter = select_more ? SELECT : 0;
+
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
+ if ((seq->flag & SELECT) != selection_filter) {
+ continue;
+ }
+ Sequence *neighbor = find_neighboring_sequence(
+ scene, seq, SEQ_SIDE_LEFT, neighbor_selection_filter);
+ if (neighbor) {
+ BLI_gset_add(neighbors, neighbor);
+ }
+ neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, neighbor_selection_filter);
+ if (neighbor) {
+ BLI_gset_add(neighbors, neighbor);
}
}
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if ((seq->flag & SELECT) == sel) {
- if (linked || (seq->tmp == NULL)) {
- /* Only get unselected neighbors. */
- neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, isel);
- if (neighbor) {
- if (sel) {
- neighbor->flag |= SELECT;
- recurs_sel_seq(neighbor);
- }
- else {
- neighbor->flag &= ~SELECT;
- }
- if (!linked) {
- neighbor->tmp = (Sequence *)1;
- }
- changed = true;
- }
- neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, isel);
- if (neighbor) {
- if (sel) {
- neighbor->flag |= SELECT;
- recurs_sel_seq(neighbor);
- }
- else {
- neighbor->flag &= ~SELECT;
- }
- if (!linked) {
- neighbor->tmp = (Sequence *)1;
- }
- changed = true;
- }
- }
+ bool changed = false;
+ GSetIterator gsi;
+ BLI_gsetIterator_init(&gsi, neighbors);
+ while (!BLI_gsetIterator_done(&gsi)) {
+ Sequence *neighbor = BLI_gsetIterator_getKey(&gsi);
+ if (select_more) {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ }
+ else {
+ neighbor->flag &= ~SELECT;
}
+ changed = true;
+ BLI_gsetIterator_step(&gsi);
}
+ BLI_gset_free(neighbors, NULL);
return changed;
}
@@ -841,7 +856,7 @@ static int sequencer_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- if (!select_more_less_seq__internal(scene, true, false)) {
+ if (!select_more_less_seq__internal(scene, true)) {
return OPERATOR_CANCELLED;
}
@@ -877,7 +892,7 @@ static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- if (!select_more_less_seq__internal(scene, false, false)) {
+ if (!select_more_less_seq__internal(scene, false)) {
return OPERATOR_CANCELLED;
}
@@ -934,7 +949,7 @@ static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, cons
selected = 1;
while (selected) {
- selected = select_more_less_seq__internal(scene, 1, 1);
+ selected = select_linked_internal(scene);
}
ED_outliner_select_sync_from_sequence_tag(C);
@@ -975,7 +990,7 @@ static int sequencer_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
selected = true;
while (selected) {
- selected = select_more_less_seq__internal(scene, true, true);
+ selected = select_linked_internal(scene);
}
ED_outliner_select_sync_from_sequence_tag(C);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index b11e2a32b87..b17482cd3a4 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -51,7 +51,6 @@
#include "RNA_access.h"
-#include "SEQ_sequencer.h"
#include "SEQ_utils.h"
#include "UI_interface.h"
@@ -334,11 +333,11 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl)
return (SpaceLink *)sseqn;
}
-static void sequencer_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void sequencer_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_SCENE:
@@ -534,12 +533,11 @@ static void sequencer_main_region_draw_overlay(const bContext *C, ARegion *regio
draw_timeline_seq_display(C, region);
}
-static void sequencer_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_SCENE:
@@ -579,14 +577,12 @@ static void sequencer_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void sequencer_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void sequencer_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -746,12 +742,11 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *region)
}
}
-static void sequencer_preview_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_preview_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_GPENCIL:
@@ -816,12 +811,11 @@ static void sequencer_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void sequencer_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_GPENCIL:
@@ -959,7 +953,7 @@ void ED_spacetype_sequencer(void)
art->listener = sequencer_main_region_listener;
BLI_addhead(&st->regiontypes, art);
- /* Hud. */
+ /* HUD. */
art = ED_area_type_hud(st->spaceid);
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_statusbar/space_statusbar.c b/source/blender/editors/space_statusbar/space_statusbar.c
index ae56b111360..0b4f483c114 100644
--- a/source/blender/editors/space_statusbar/space_statusbar.c
+++ b/source/blender/editors/space_statusbar/space_statusbar.c
@@ -34,7 +34,6 @@
#include "RNA_access.h"
#include "UI_interface.h"
-#include "UI_view2d.h"
#include "WM_api.h"
#include "WM_message.h"
@@ -95,12 +94,11 @@ static void statusbar_keymap(struct wmKeyConfig *UNUSED(keyconf))
{
}
-static void statusbar_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void statusbar_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -131,14 +129,11 @@ static void statusbar_header_region_listener(wmWindow *UNUSED(win),
}
}
-static void statusbar_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void statusbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 0f5ac5abe1d..ea55eaea388 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -33,7 +33,6 @@
#include "BKE_global.h"
#include "BKE_lib_id.h"
#include "BKE_screen.h"
-#include "BKE_text.h"
#include "ED_screen.h"
#include "ED_space_api.h"
@@ -47,7 +46,6 @@
#include "RNA_access.h"
-#include "GPU_framebuffer.h"
#include "text_format.h"
#include "text_intern.h" /* own include */
@@ -122,11 +120,10 @@ static SpaceLink *text_duplicate(SpaceLink *sl)
return (SpaceLink *)stextn;
}
-static void text_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void text_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceText *st = area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 849766851aa..883556948e2 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -722,7 +722,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *region)
void text_drawcache_tag_update(SpaceText *st, int full)
{
- /* this happens if text editor ops are caled from python */
+ /* This happens if text editor ops are called from Python. */
if (st == NULL) {
return;
}
@@ -1010,13 +1010,16 @@ static void draw_textscroll(const SpaceText *st, rcti *scroll, rcti *back)
BLI_rcti_size_y(&st->runtime.scroll_region_select));
UI_GetThemeColor3fv(TH_HILITE, col);
col[3] = 0.18f;
- UI_draw_roundbox_aa(true,
- st->runtime.scroll_region_select.xmin + 1,
- st->runtime.scroll_region_select.ymin,
- st->runtime.scroll_region_select.xmax - 1,
- st->runtime.scroll_region_select.ymax,
- rad,
- col);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = st->runtime.scroll_region_select.xmin + 1,
+ .xmax = st->runtime.scroll_region_select.xmax - 1,
+ .ymin = st->runtime.scroll_region_select.ymin,
+ .ymax = st->runtime.scroll_region_select.ymax,
+ },
+ true,
+ rad,
+ col);
}
/*********************** draw documentation *******************************/
@@ -1180,7 +1183,14 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
}
/* not needed but stands out nicer */
- UI_draw_box_shadow(220, x, y - boxh, x + boxw, y);
+ UI_draw_box_shadow(
+ &(const rctf){
+ .xmin = x,
+ .xmax = x + boxw,
+ .ymin = y - boxh,
+ .ymax = y,
+ },
+ 220);
uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
diff --git a/source/blender/editors/space_text/text_format.c b/source/blender/editors/space_text/text_format.c
index d099f2a20d8..66765206fa6 100644
--- a/source/blender/editors/space_text/text_format.c
+++ b/source/blender/editors/space_text/text_format.c
@@ -237,7 +237,7 @@ bool ED_text_is_syntax_highlight_supported(Text *text)
const char *text_ext = BLI_path_extension(text->id.name + 2);
if (text_ext == NULL) {
- /* Extensionless datablocks are considered highlightable as Python. */
+ /* Extensionless data-blocks are considered highlightable as Python. */
return true;
}
text_ext++; /* skip the '.' */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 932bacfb8a0..526285c076a 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -3832,7 +3832,7 @@ static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, const wmEve
switch (BKE_text_file_modified_check(text)) {
case 1:
if (text->flags & TXT_ISDIRTY) {
- /* modified locally and externally, ahhh. offer more possibilities. */
+ /* Modified locally and externally, ah. offer more possibilities. */
pup = UI_popup_menu_begin(
C, IFACE_("File Modified Outside and Inside Blender"), ICON_NONE);
layout = UI_popup_menu_layout(pup);
diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.c
index 61b786b2b13..f55db8c3cc9 100644
--- a/source/blender/editors/space_text/text_undo.c
+++ b/source/blender/editors/space_text/text_undo.c
@@ -196,14 +196,19 @@ static bool text_undosys_step_encode(struct bContext *C,
return true;
}
-static void text_undosys_step_decode(
- struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p, int dir, bool is_final)
+static void text_undosys_step_decode(struct bContext *C,
+ struct Main *UNUSED(bmain),
+ UndoStep *us_p,
+ const eUndoStepDir dir,
+ bool is_final)
{
+ BLI_assert(dir != STEP_INVALID);
+
TextUndoStep *us = (TextUndoStep *)us_p;
Text *text = us->text_ref.ptr;
TextState *state;
- if ((us->states[0].buf_array_state != NULL) && (dir == -1) && !is_final) {
+ if ((us->states[0].buf_array_state != NULL) && (dir == STEP_UNDO) && !is_final) {
state = &us->states[0];
}
else {
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index dc357cdd355..419721cf89e 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -38,7 +38,6 @@
#include "ED_screen.h"
#include "ED_space_api.h"
-#include "ED_undo.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -129,12 +128,11 @@ static void topbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *regi
ED_region_header_init(region);
}
-static void topbar_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void topbar_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -160,12 +158,11 @@ static void topbar_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void topbar_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void topbar_header_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -191,14 +188,12 @@ static void topbar_header_listener(wmWindow *UNUSED(win),
}
}
-static void topbar_header_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void topbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 3efdee9cec9..d4692f156d3 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -183,46 +183,20 @@ static void userpref_execute_region_init(wmWindowManager *wm, ARegion *region)
region->v2d.keepzoom |= V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y;
}
-static void userpref_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_main_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
-static void userpref_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_header_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
-#if 0
- switch (wmn->category) {
- default:
- break;
- }
-#endif
}
-static void userpref_navigation_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_navigation_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
-static void userpref_execute_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_execute_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
/* only called once, from space/spacetypes.c */
diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c
index f05d6df9944..7c799f0d97b 100644
--- a/source/blender/editors/space_userpref/userpref_ops.c
+++ b/source/blender/editors/space_userpref/userpref_ops.c
@@ -28,10 +28,8 @@
#include "BLI_listbase.h"
#include "BKE_context.h"
-#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_preferences.h"
-#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -39,8 +37,6 @@
#include "UI_interface.h"
-#include "../interface/interface_intern.h"
-
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 4c168c7a243..26441bde6b6 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -393,7 +393,7 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *region)
keymap = WM_keymap_ensure(wm->defaultconf, "Paint Vertex Selection (Weight, Vertex)", 0, 0);
WM_event_add_keymap_handler(&region->handlers, keymap);
- /* Before 'Weight/Vertex Paint' so adding curve points is not overriden. */
+ /* Before 'Weight/Vertex Paint' so adding curve points is not overridden. */
keymap = WM_keymap_ensure(wm->defaultconf, "Paint Curve", 0, 0);
WM_event_add_keymap_handler(&region->handlers, keymap);
@@ -469,16 +469,30 @@ static bool view3d_drop_in_main_region_poll(bContext *C, const wmEvent *event)
return ED_region_overlap_isect_any_xy(area, &event->x) == false;
}
-static ID *view3d_drop_id_in_main_region_poll_id(bContext *C,
- wmDrag *drag,
- const wmEvent *event,
- ID_Type id_type)
+static ID_Type view3d_drop_id_in_main_region_poll_get_id_type(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event)
{
- ScrArea *area = CTX_wm_area(C);
+ const ScrArea *area = CTX_wm_area(C);
+
if (ED_region_overlap_isect_any_xy(area, &event->x)) {
- return NULL;
+ return 0;
+ }
+ if (!view3d_drop_in_main_region_poll(C, event)) {
+ return 0;
+ }
+
+ ID *local_id = WM_drag_get_local_ID(drag, 0);
+ if (local_id) {
+ return GS(local_id->name);
+ }
+
+ wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
+ if (asset_drag) {
+ return asset_drag->id_type;
}
- return view3d_drop_in_main_region_poll(C, event) ? WM_drag_get_local_ID(drag, id_type) : NULL;
+
+ return 0;
}
static bool view3d_drop_id_in_main_region_poll(bContext *C,
@@ -490,7 +504,7 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C,
return false;
}
- return WM_drag_get_local_ID(drag, id_type) || WM_drag_get_asset_data(drag, id_type);
+ return WM_drag_is_ID_type(drag, id_type);
}
static bool view3d_ob_drop_poll(bContext *C,
@@ -522,9 +536,9 @@ static bool view3d_object_data_drop_poll(bContext *C,
const wmEvent *event,
const char **r_tooltip)
{
- ID *id = view3d_drop_id_in_main_region_poll_id(C, drag, event, 0);
- if (id != NULL) {
- if (BKE_object_obdata_to_type(id) != -1) {
+ ID_Type id_type = view3d_drop_id_in_main_region_poll_get_id_type(C, drag, event);
+ if (id_type) {
+ if (OB_DATA_SUPPORT_ID(id_type)) {
*r_tooltip = TIP_("Create object instance from object-data");
return true;
}
@@ -545,7 +559,7 @@ static bool view3d_ima_drop_poll(bContext *C,
return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
}
- return WM_drag_get_local_ID(drag, ID_IM) || WM_drag_get_asset_data(drag, ID_IM);
+ return WM_drag_is_ID_type(drag, ID_IM);
}
static bool view3d_ima_bg_is_camera_view(bContext *C)
@@ -629,7 +643,7 @@ static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
static void view3d_id_drop_copy_with_type(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_get_local_ID(drag, 0);
+ ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
RNA_enum_set(drop->ptr, "type", GS(id->name));
@@ -784,9 +798,13 @@ static void *view3d_main_region_duplicate(void *poin)
return NULL;
}
-static void view3d_main_region_listener(
- wmWindow *win, ScrArea *area, ARegion *region, wmNotifier *wmn, const Scene *scene)
+static void view3d_main_region_listener(const wmRegionListenerParams *params)
{
+ wmWindow *window = params->window;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+ const Scene *scene = params->scene;
View3D *v3d = area->spacedata.first;
RegionView3D *rv3d = region->regiondata;
wmGizmoMap *gzmap = region->gizmo_map;
@@ -1007,10 +1025,10 @@ static void view3d_main_region_listener(
ED_view3d_xr_shading_update(G_MAIN->wm.first, v3d, scene);
#endif
- ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ ViewLayer *view_layer = WM_window_get_active_view_layer(window);
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer);
if (depsgraph) {
- ED_render_view3d_update(depsgraph, win, area, true);
+ ED_render_view3d_update(depsgraph, window, area, true);
}
}
ED_region_tag_redraw(region);
@@ -1048,14 +1066,13 @@ static void view3d_main_region_listener(
}
}
-static void view3d_main_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ const bContext *C = params->context;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
/* Developer note: there are many properties that impact 3D view drawing,
* so instead of subscribing to individual properties, just subscribe to types
* accepting some redundant redraws.
@@ -1170,12 +1187,11 @@ static void view3d_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void view3d_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void view3d_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -1240,14 +1256,11 @@ static void view3d_header_region_listener(wmWindow *UNUSED(win),
#endif
}
-static void view3d_header_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void view3d_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgParams_RNA msg_key_params = {{0}};
/* Only subscribe to types. */
@@ -1385,12 +1398,11 @@ static void view3d_buttons_region_layout(const bContext *C, ARegion *region)
ED_view3d_buttons_region_layout_ex(C, region, NULL);
}
-static void view3d_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void view3d_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -1509,11 +1521,10 @@ static void view3d_tools_region_draw(const bContext *C, ARegion *region)
}
/* area (not region) level listener */
-static void space_view3d_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- struct wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void space_view3d_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
View3D *v3d = area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index 11643960595..0edd6aeb2ca 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -50,12 +50,8 @@
#include "DEG_depsgraph.h"
-#include "ED_screen.h"
-
#include "view3d_intern.h" /* own include */
-#include "BLI_strict_flags.h"
-
typedef struct View3DCameraControl {
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 9982d44b6be..478f48700ea 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -165,7 +165,7 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
}
- /* calculate pixelsize factor once, is used for lights and obcenters */
+ /* Calculate pixel-size factor once, this is used for lights and object-centers. */
{
/* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
* because of float point precision problems at large values T23908. */
@@ -723,15 +723,24 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
}
if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
- UI_draw_safe_areas(
- shdr_pos, x1, x2, y1, y2, scene->safe_areas.title, scene->safe_areas.action);
+ UI_draw_safe_areas(shdr_pos,
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
+ scene->safe_areas.title,
+ scene->safe_areas.action);
if (ca->flag & CAM_SHOW_SAFE_CENTER) {
UI_draw_safe_areas(shdr_pos,
- x1,
- x2,
- y1,
- y2,
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
scene->safe_areas.title_center,
scene->safe_areas.action_center);
}
@@ -1960,13 +1969,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
/* XXX(jbakker): `do_color_management` should be controlled by the caller. Currently when doing a
* viewport render animation and saving to an 8bit file format, color management would be applied
* twice. Once here, and once when saving the saving to disk. In this case the Save As Render
- * option cannot be controlled either. But when doing an offscreen render you want to do the
+ * option cannot be controlled either. But when doing an off-screen render you want to do the
* color management here.
*
- * This option was added here to increase the performance when rendering for a playblast. 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. */
+ * This option was added here to increase the performance for quick view-port preview renders.
+ * 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);
ED_view3d_draw_offscreen(depsgraph,
scene,
@@ -2335,7 +2344,7 @@ void ED_view3d_depth_update(ARegion *region)
}
}
-/* Utility function to find the closest Z value, use for autodepth. */
+/* Utility function to find the closest Z value, use for auto-depth. */
float view3d_depth_near(ViewDepths *d)
{
/* Convert to float for comparisons. */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index ab4e7be88fe..2f8cd5a7517 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2025,7 +2025,7 @@ static float viewzoom_scale_value(const rcti *winrct,
{
float zfac;
- if (viewzoom == USER_ZOOM_CONT) {
+ if (viewzoom == USER_ZOOM_CONTINUE) {
double time = PIL_check_seconds_timer();
float time_step = (float)(time - *r_timer_lastdraw);
float fac;
@@ -2043,7 +2043,6 @@ static float viewzoom_scale_value(const rcti *winrct,
fac = -fac;
}
- /* oldstyle zoom */
zfac = 1.0f + ((fac / 20.0f) * time_step);
*r_timer_lastdraw = time;
}
@@ -2405,7 +2404,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
vod->prev.time = PIL_check_seconds_timer();
@@ -2888,7 +2887,7 @@ static void view3d_from_minmax(bContext *C,
});
}
- /* smooth view does viewlock RV3D_BOXVIEW copy */
+ /* Smooth-view does view-lock #RV3D_BOXVIEW copy. */
}
/**
@@ -3021,7 +3020,6 @@ void VIEW3D_OT_view_all(wmOperatorType *ot)
* Move & Zoom the view to fit selected contents.
* \{ */
-/* like a localview without local!, was centerview() in 2.4x */
static int viewselected_exec(bContext *C, wmOperator *op)
{
ARegion *region = CTX_wm_region(C);
@@ -3282,7 +3280,7 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op)
ED_view3d_smooth_view(
C, v3d, region, smooth_viewtx, &(const V3D_SmoothParams){.ofs = new_ofs});
- /* smooth view does viewlock RV3D_BOXVIEW copy */
+ /* Smooth view does view-lock #RV3D_BOXVIEW copy. */
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 6824c526888..2d499cf85c7 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -48,7 +48,7 @@
#include "ED_screen.h"
#include "ED_space_api.h"
-#include "PIL_time.h" /* smoothview */
+#include "PIL_time.h" /* Smooth-view. */
#include "UI_interface.h"
#include "UI_resources.h"
@@ -84,7 +84,7 @@ enum {
FLY_MODAL_PRECISION_DISABLE,
FLY_MODAL_FREELOOK_ENABLE,
FLY_MODAL_FREELOOK_DISABLE,
- FLY_MODAL_SPEED, /* mousepan typically */
+ FLY_MODAL_SPEED, /* mouse-pan typically. */
};
/* relative view axis locking - xlock, zlock */
@@ -537,7 +537,7 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event)
fly->state = FLY_CONFIRM;
break;
- /* speed adjusting with mousepan (trackpad) */
+ /* Speed adjusting with mouse-pan (track-pad). */
case FLY_MODAL_SPEED: {
float fac = 0.02f * (event->prevy - event->y);
@@ -768,7 +768,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
/* this is the direction that's added to the view offset per redraw */
float dvec[3] = {0, 0, 0};
- /* Camera Uprighting variables */
+ /* Camera Up-righting variables. */
float moffset[2]; /* mouse offset from the views center */
float tmp_quat[4]; /* used for rotating the view */
@@ -950,7 +950,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
}
}
- /* only apply xcorrect when mouse isn't applying x rot */
+ /* Only apply X-axis correction when mouse isn't applying x rotation. */
if (fly->xlock == FLY_AXISLOCK_STATE_ACTIVE && moffset[1] == 0) {
float upvec[3];
copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
index 242a0a802a6..98597cb2986 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
@@ -22,7 +22,6 @@
#include "BKE_context.h"
#include "BKE_layer.h"
-#include "BKE_object.h"
#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
index 7a201d8841c..6fa974cdb09 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
@@ -22,7 +22,6 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_object.h"
#include "DNA_object_types.h"
@@ -45,14 +44,17 @@
/** \name View3D Navigation Gizmo Group
* \{ */
-/* Offset from screen edge. */
-#define GIZMO_OFFSET_FAC 1.2f
/* Size of main icon. */
-#define GIZMO_SIZE 80
-/* Factor for size of smaller button. */
-#define GIZMO_MINI_FAC 0.35f
-/* How much mini buttons offset from the primary. */
-#define GIZMO_MINI_OFFSET_FAC 0.38f
+#define GIZMO_SIZE U.gizmo_size_navigate_v3d
+
+/* Main gizmo offset from screen edges in unscaled pixels. */
+#define GIZMO_OFFSET 10.0f
+
+/* Width of smaller buttons in unscaled pixels. */
+#define GIZMO_MINI_SIZE 28.0f
+
+/* Margin around the smaller buttons. */
+#define GIZMO_MINI_OFFSET 2.0f
enum {
GZ_INDEX_MOVE = 0,
@@ -174,7 +176,7 @@ static void WIDGETGROUP_navigate_setup(const bContext *C, wmGizmoGroup *gzgroup)
}
/* may be overwritten later */
- gz->scale_basis = (GIZMO_SIZE * GIZMO_MINI_FAC) / 2;
+ gz->scale_basis = GIZMO_MINI_SIZE / 2.0f;
if (info->icon != 0) {
PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon");
RNA_property_enum_set(gz->ptr, prop, info->icon);
@@ -212,7 +214,7 @@ static void WIDGETGROUP_navigate_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
wmGizmo *gz = navgroup->gz_array[GZ_INDEX_ROTATE];
- gz->scale_basis = GIZMO_SIZE / 2;
+ gz->scale_basis = GIZMO_SIZE / 2.0f;
const char mapping[6] = {
RV3D_VIEW_LEFT,
RV3D_VIEW_RIGHT,
@@ -263,9 +265,8 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g
const bool show_navigate = (U.uiflag & USER_SHOW_GIZMO_NAVIGATE) != 0;
const bool show_rotate_gizmo = (U.mini_axis_type == USER_MINI_AXIS_TYPE_GIZMO);
- const float icon_size = GIZMO_SIZE;
- const float icon_offset = (icon_size * 0.52f) * GIZMO_OFFSET_FAC * UI_DPI_FAC;
- const float icon_offset_mini = icon_size * GIZMO_MINI_OFFSET_FAC * UI_DPI_FAC;
+ const float icon_offset = ((GIZMO_SIZE / 2.0f) + GIZMO_OFFSET) * UI_DPI_FAC;
+ const float icon_offset_mini = (GIZMO_MINI_SIZE + GIZMO_MINI_OFFSET) * UI_DPI_FAC;
const float co_rotate[2] = {
rect_visible->xmax - icon_offset,
rect_visible->ymax - icon_offset,
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 8f3d40584aa..4ac16e8fbe8 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
@@ -40,6 +40,8 @@
#include "GPU_matrix.h"
#include "GPU_state.h"
+#include "BLF_api.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -53,169 +55,34 @@
#include "view3d_intern.h"
-#define USE_AXIS_FONT
-#define USE_FADE_BACKGROUND
-
-#ifdef USE_AXIS_FONT
-# include "BLF_api.h"
-#endif
-
-#define DIAL_RESOLUTION 32
-
-/* Sizes of axis spheres containing XYZ characters. */
-#define AXIS_HANDLE_SIZE_FG 0.19f
-/* When pointing away from the view. */
-#define AXIS_HANDLE_SIZE_BG 0.15f
-/* How far axis handles are away from the center. */
-#define AXIS_HANDLE_OFFSET (1.0f - AXIS_HANDLE_SIZE_FG)
-
-struct AxisDrawInfo {
- /* Matrix is needed for screen-aligned font drawing. */
-#ifdef USE_AXIS_FONT
- float matrix_final[4][4];
-#endif
-#ifdef USE_FADE_BACKGROUND
- float color_bg[3];
-#endif
-};
-
-#ifndef USE_AXIS_FONT
-/**
- * \param viewmat_local_unit: is typically the 'rv3d->viewmatob'
- * copied into a 3x3 matrix and normalized.
- */
-static void draw_xyz_wire(
- uint pos_id, const float viewmat_local_unit[3][3], const float c[3], float size, int axis)
-{
- int line_type;
- float buffer[4][3];
- int n = 0;
-
- float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f};
- float dim = size * 0.1f;
- float dx[3], dy[3];
-
- dx[0] = dim;
- dx[1] = 0.0f;
- dx[2] = 0.0f;
- dy[0] = 0.0f;
- dy[1] = dim;
- dy[2] = 0.0f;
-
- switch (axis) {
- case 0: /* x axis */
- line_type = GPU_PRIM_LINES;
-
- /* bottom left to top right */
- negate_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
- copy_v3_v3(v2, dx);
- add_v3_v3(v2, dy);
-
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
-
- /* top left to bottom right */
- mul_v3_fl(dy, 2.0f);
- add_v3_v3(v1, dy);
- sub_v3_v3(v2, dy);
-
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
-
- break;
- case 1: /* y axis */
- line_type = GPU_PRIM_LINES;
-
- /* bottom left to top right */
- mul_v3_fl(dx, 0.75f);
- negate_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
- copy_v3_v3(v2, dx);
- add_v3_v3(v2, dy);
-
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
-
- /* top left to center */
- mul_v3_fl(dy, 2.0f);
- add_v3_v3(v1, dy);
- zero_v3(v2);
-
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
-
- break;
- case 2: /* z axis */
- line_type = GPU_PRIM_LINE_STRIP;
-
- /* start at top left */
- negate_v3_v3(v1, dx);
- add_v3_v3(v1, dy);
-
- copy_v3_v3(buffer[n++], v1);
-
- mul_v3_fl(dx, 2.0f);
- add_v3_v3(v1, dx);
+/* Radius of the entire background. */
+#define WIDGET_RADIUS ((U.gizmo_size_navigate_v3d / 2.0f) * UI_DPI_FAC)
- copy_v3_v3(buffer[n++], v1);
+/* Sizes of axis spheres containing XYZ characters in relation to above. */
+#define AXIS_HANDLE_SIZE 0.20f
- mul_v3_fl(dy, 2.0f);
- sub_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
+#define AXIS_LINE_WIDTH ((U.gizmo_size_navigate_v3d / 40.0f) * U.pixelsize)
+#define AXIS_RING_WIDTH ((U.gizmo_size_navigate_v3d / 60.0f) * U.pixelsize)
+#define AXIS_TEXT_SIZE (WIDGET_RADIUS * AXIS_HANDLE_SIZE * 1.25f)
- copy_v3_v3(buffer[n++], v1);
+/* distance within this from center is considered positive. */
+#define AXIS_DEPTH_BIAS 0.01f
- add_v3_v3(v1, dx);
-
- copy_v3_v3(buffer[n++], v1);
-
- break;
- default:
- BLI_assert(0);
- return;
- }
-
- for (int i = 0; i < n; i++) {
- mul_transposed_m3_v3((float(*)[3])viewmat_local_unit, buffer[i]);
- add_v3_v3(buffer[i], c);
- }
-
- immBegin(line_type, n);
- for (int i = 0; i < n; i++) {
- immVertex3fv(pos_id, buffer[i]);
- }
- immEnd();
-}
-#endif /* !USE_AXIS_FONT */
-
-/**
- * \param draw_info: Extra data needed for drawing.
- */
-static void axis_geom_draw(const wmGizmo *gz,
- const float color[4],
- const bool select,
- const struct AxisDrawInfo *draw_info)
+static void gizmo_axis_draw(const bContext *C, wmGizmo *gz)
{
- float viewport[4];
- GPU_viewport_size_get_f(viewport);
-
- GPUVertFormat *format = immVertexFormat();
- const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
struct {
float depth;
char index;
char axis;
+ char axis_opposite;
bool is_pos;
} axis_order[6] = {
- {-gz->matrix_offset[0][2], 0, 0, false},
- {+gz->matrix_offset[0][2], 1, 0, true},
- {-gz->matrix_offset[1][2], 2, 1, false},
- {+gz->matrix_offset[1][2], 3, 1, true},
- {-gz->matrix_offset[2][2], 4, 2, false},
- {+gz->matrix_offset[2][2], 5, 2, true},
+ {-gz->matrix_offset[0][2], 0, 0, 1, false},
+ {+gz->matrix_offset[0][2], 1, 0, 0, true},
+ {-gz->matrix_offset[1][2], 2, 1, 3, false},
+ {+gz->matrix_offset[1][2], 3, 1, 2, true},
+ {-gz->matrix_offset[2][2], 4, 2, 5, false},
+ {+gz->matrix_offset[2][2], 5, 2, 4, true},
};
int axis_align = -1;
@@ -226,25 +93,35 @@ static void axis_geom_draw(const wmGizmo *gz,
}
}
- /* Show backwards pointing highlight on-top (else we can't see it at all). */
- if ((select == false) && (gz->highlight_part > 0) && (axis_align != -1)) {
- if (axis_order[gz->highlight_part - 1].is_pos == false) {
- axis_order[gz->highlight_part - 1].depth = FLT_MAX;
- }
- }
-
qsort(&axis_order, ARRAY_SIZE(axis_order), sizeof(axis_order[0]), BLI_sortutil_cmp_float);
- static const float axis_highlight[4] = {1, 1, 1, 1};
- static const float axis_black[4] = {0, 0, 0, 1};
- static float axis_color[3][4];
+ /* When the cursor is over any of the gizmos (show circle backdrop). */
+ const bool is_active = ((gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0);
- const float axis_depth_bias = 0.01f;
- const float sphere_scale = 1.15f;
- /* TODO(fclem): Is there a way to get the widget radius? */
- const float widget_pix_size = 40.0f * U.dpi_fac;
+ /* Background color of the View3D, used to mix colors. */
+ float view_color[4];
+ ED_view3d_background_color_get(CTX_data_scene(C), CTX_wm_view3d(C), view_color);
+ view_color[3] = 1.0f;
+
+ float matrix_screen[4][4];
+ float matrix_unit[4][4];
+ unit_m4(matrix_unit);
+ WM_gizmo_calc_matrix_final_params(gz,
+ &((struct WM_GizmoMatrixParams){
+ .matrix_offset = matrix_unit,
+ }),
+ matrix_screen);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_screen);
+
+ GPUVertFormat *format = immVertexFormat();
+ const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ const uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+
+ static float axis_color[3][4];
-#ifdef USE_AXIS_FONT
struct {
float matrix[4][4];
float matrix_m3[3][3];
@@ -252,38 +129,29 @@ static void axis_geom_draw(const wmGizmo *gz,
int id;
} font;
- if (select == false) {
- font.id = blf_mono_font;
- BLF_disable(font.id, BLF_ROTATION | BLF_SHADOW | BLF_MATRIX | BLF_ASPECT | BLF_WORD_WRAP);
- BLF_color4fv(font.id, axis_black);
- BLF_size(font.id, 12 * U.dpi_fac, 72);
-
- /* The view matrix is used to position the text. */
- BLF_position(font.id, 0, 0, 0);
-
- /* Calculate the inverse of the (matrix_final * matrix_offset).
- * This allows us to use the final location, while reversing the rotation so fonts
- * show without any rotation. */
- float m3[3][3];
- float m3_offset[3][3];
- copy_m3_m4(m3, draw_info->matrix_final);
- copy_m3_m4(m3_offset, gz->matrix_offset);
- mul_m3_m3m3(m3, m3, m3_offset);
- copy_m3_m3(font.matrix_m3_invert, m3);
- invert_m3(m3);
- copy_m3_m3(font.matrix_m3, m3);
- copy_m4_m3(font.matrix, m3);
- }
-#endif
-
- /* When the cursor is over any of the gizmos (show circle backdrop). */
- const bool is_active = (color[3] != 0.0f);
-
- const float clip_range = gz->scale_final * sphere_scale;
- bool use_project_matrix = (clip_range >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT);
+ 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_position(font.id, 0, 0, 0);
+
+ /* Calculate the inverse of the (matrix_final * matrix_offset).
+ * This allows us to use the final location, while reversing the rotation so fonts
+ * show without any rotation. */
+ float m3[3][3];
+ float m3_offset[3][3];
+ copy_m3_m4(m3, matrix_screen);
+ copy_m3_m4(m3_offset, gz->matrix_offset);
+ mul_m3_m3m3(m3, m3, m3_offset);
+ copy_m3_m3(font.matrix_m3_invert, m3);
+ invert_m3(m3);
+ copy_m3_m3(font.matrix_m3, m3);
+ copy_m4_m3(font.matrix, m3);
+
+ bool use_project_matrix = (gz->scale_final >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT);
if (use_project_matrix) {
GPU_matrix_push_projection();
- GPU_matrix_ortho_set_z(-clip_range, clip_range);
+ GPU_matrix_ortho_set_z(-gz->scale_final, gz->scale_final);
}
UI_draw_roundbox_corner_set(UI_CNR_ALL);
@@ -291,263 +159,161 @@ static void axis_geom_draw(const wmGizmo *gz,
/* Circle defining active area. */
if (is_active) {
- immUnbindProgram();
-
- float rad = widget_pix_size;
+ const float rad = WIDGET_RADIUS;
GPU_matrix_push();
GPU_matrix_scale_1f(1.0f / rad);
-
- UI_draw_roundbox_4fv(true, -rad, -rad, rad, rad, rad, color);
-
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = -rad,
+ .xmax = rad,
+ .ymin = -rad,
+ .ymax = rad,
+ },
+ true,
+ rad,
+ gz->color_hi);
GPU_matrix_pop();
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
}
- GPU_matrix_push();
GPU_matrix_mul(gz->matrix_offset);
for (int axis_index = 0; axis_index < ARRAY_SIZE(axis_order); axis_index++) {
const int index = axis_order[axis_index].index;
const int axis = axis_order[axis_index].axis;
const bool is_pos = axis_order[axis_index].is_pos;
- const bool is_highlight = index + 1 == gz->highlight_part;
+ const float depth = axis_order[axis_index].depth;
+ const bool is_behind = (depth <= (AXIS_DEPTH_BIAS * (is_pos ? -1 : 1)));
+ bool is_aligned_front = (axis_align != -1 && axis_align == axis && !is_behind);
+ bool is_aligned_back = (axis_align != -1 && axis_align == axis && is_behind);
+
+ const float v[3] = {0, 0, (1.0f - AXIS_HANDLE_SIZE) * (is_pos ? 1 : -1)};
+ const float v_final[3] = {v[(axis + 2) % 3], v[(axis + 1) % 3], v[axis]};
+
+ bool is_highlight = index + 1 == gz->highlight_part;
+ /* Check if highlight part is the other side when axis aligned. */
+ if (is_aligned_front && (axis_order[axis_index].axis_opposite + 1 == gz->highlight_part)) {
+ is_highlight = true;
+ }
UI_GetThemeColor3fv(TH_AXIS_X + axis, axis_color[axis]);
axis_color[axis][3] = 1.0f;
- const int index_z = axis;
- const int index_y = (axis + 1) % 3;
- const int index_x = (axis + 2) % 3;
-
- bool ok = true;
-
- /* Skip view align axis when selecting (allows to switch to opposite side). */
- if (select && ((axis_align == axis) && (gz->matrix_offset[axis][2] > 0.0f) == is_pos)) {
- ok = false;
+ /* Color that is full at front, but 50% view background when in back. */
+ float fading_color[4];
+ interp_v4_v4v4(fading_color, view_color, axis_color[axis], ((depth + 1) * 0.25) + 0.5);
+
+ /* Color that is midway between front and back. */
+ float middle_color[4];
+ interp_v4_v4v4(middle_color, view_color, axis_color[axis], 0.75f);
+
+ GPU_blend(GPU_BLEND_ALPHA);
+
+ /* Axis Line. */
+ if (is_pos || axis_align != -1) {
+
+ /* Extend slightly to meet better at the center. */
+ float v_start[3] = {0.0f, 0.0f, 0.0f};
+ mul_v3_v3fl(v_start, v_final, -(AXIS_LINE_WIDTH / WIDGET_RADIUS * 0.66f));
+
+ /* Decrease length of line by ball radius. */
+ float v_end[3] = {0.0f, 0.0f, 0.0f};
+ mul_v3_v3fl(v_end, v_final, 1.0f - AXIS_HANDLE_SIZE);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR);
+ immUniform2fv("viewportSize", &viewport_size[2]);
+ immUniform1f("lineWidth", AXIS_LINE_WIDTH);
+ immBegin(GPU_PRIM_LINES, 2);
+ immAttr4fv(color_id, middle_color);
+ immVertex3fv(pos_id, v_start);
+ immAttr4fv(color_id, fading_color);
+ immVertex3fv(pos_id, v_end);
+ immEnd();
+ immUnbindProgram();
}
- if (ok) {
- /* Check aligned, since the front axis won't display in this case,
- * and we want to make sure all 3 axes have a character at all times. */
- const bool show_axis_char = (is_pos || (axis == axis_align));
- const float v[3] = {0, 0, AXIS_HANDLE_OFFSET * (is_pos ? 1 : -1)};
- const float v_final[3] = {v[index_x], v[index_y], v[index_z]};
- const float *color_current = is_highlight ? axis_highlight : axis_color[axis];
- float color_current_fade[4];
-
- /* Flip the faded state when axis aligned, since we're hiding the front-mode axis
- * otherwise we see the color for the back-most axis, which is useful for
- * click-to-rotate 180d but not useful to visualize.
- *
- * Use depth bias so axis-aligned views show the positive axis as being in-front.
- * This is a detail so primary axes show as dominant.
- */
- const bool is_pos_color = (axis_order[axis_index].depth >
- (axis_depth_bias * (is_pos ? -1 : 1)));
-
- if (select == false) {
-#ifdef USE_FADE_BACKGROUND
- interp_v3_v3v3(
- color_current_fade, draw_info->color_bg, color_current, is_highlight ? 1.0 : 0.5f);
- color_current_fade[3] = color_current[3];
-#else
- copy_v4_v4(color_current_fade, color_current);
- color_current_fade[3] *= 0.2;
-#endif
- }
- else {
- copy_v4_fl(color_current_fade, 1.0f);
- }
-
- /* Axis Line. */
- if (is_pos) {
- float v_start[3];
- immUnbindProgram();
-
- GPU_blend(GPU_BLEND_ALPHA);
-
- immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
- immUniform2fv("viewportSize", &viewport[2]);
- immUniform1f("lineWidth", 2.0f * U.pixelsize);
- immUniformColor4fv(is_pos_color ? color_current : color_current_fade);
- immBegin(GPU_PRIM_LINES, 2);
- if (axis_align == -1) {
- zero_v3(v_start);
+ /* Axis Ball. */
+ if (!is_aligned_back) {
+ float *inner_color = fading_color;
+ float *outline_color = fading_color;
+ float negative_color[4];
+ if (!is_pos) {
+ if (is_aligned_front) {
+ interp_v4_v4v4(
+ negative_color, (float[4]){1.0f, 1.0f, 1.0f, 1.0f}, axis_color[axis], 0.5f);
+ negative_color[3] = MIN2(depth + 1, 1.0f);
+ outline_color = negative_color;
}
else {
- /* When axis aligned we don't draw the front most axis
- * (allowing us to switch to the opposite side).
- * In this case don't draw lines over axis pointing away from us
- * because it obscures character and looks noisy.
- */
- mul_v3_v3fl(v_start, v_final, 0.3f);
+ interp_v4_v4v4(negative_color, view_color, axis_color[axis], 0.25f);
+ negative_color[3] = MIN2(depth + 1, 1.0f);
+ inner_color = negative_color;
}
- immVertex3fv(pos_id, v_start);
- immVertex3fv(pos_id, v_final);
- immEnd();
-
- immUnbindProgram();
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
}
- /* Axis Ball. */
-#ifdef USE_AXIS_FONT
- if (select == false) {
- immUnbindProgram();
-
- GPU_matrix_push();
- GPU_matrix_translate_3fv(v_final);
- GPU_matrix_mul(font.matrix);
-
- float rad = widget_pix_size * (is_pos ? AXIS_HANDLE_SIZE_FG : AXIS_HANDLE_SIZE_BG);
-
- /* Black outlines for negative axis balls, otherwise they can be hard to see since
- * they use a faded color which can be similar to the circle backdrop in tone. */
- if (is_active && !is_highlight && !is_pos && !select && !(axis_align == axis)) {
- static const float axis_black_faded[4] = {0.0f, 0.0f, 0.0f, 0.2f};
- float outline = rad * sphere_scale;
- UI_draw_roundbox_4fv(
- true, -outline, -outline, outline, outline, outline, axis_black_faded);
- }
-
- const float *col = is_pos_color ? color_current : color_current_fade;
- UI_draw_roundbox_4fv(true, -rad, -rad, rad, rad, rad, col);
-
- GPU_matrix_pop();
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- }
- else
-#endif
- {
- GPU_matrix_push();
- GPU_matrix_translate_3fv(v_final);
- GPU_matrix_scale_1f(is_pos ? AXIS_HANDLE_SIZE_FG : AXIS_HANDLE_SIZE_BG);
-
- GPUBatch *sphere = GPU_batch_preset_sphere(0);
- GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
-
- /* Black outlines for negative axis balls, otherwise they can be hard to see since
- * they use a faded color which can be similar to the circle backdrop in tone. */
- if (is_active && !is_highlight && !is_pos && !select && !(axis_align == axis)) {
- static const float axis_black_faded[4] = {0, 0, 0, 0.2f};
- GPU_matrix_scale_1f(sphere_scale);
- GPU_batch_uniform_4fv(sphere, "color", axis_black_faded);
- GPU_batch_draw(sphere);
- GPU_matrix_scale_1f(1.0 / sphere_scale);
- }
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(v_final);
+ GPU_matrix_mul(font.matrix);
+ /* Size change from back to front: 0.92f - 1.08f. */
+ float scale = ((depth + 1) * 0.08f) + 0.92f;
+ const float rad = WIDGET_RADIUS * AXIS_HANDLE_SIZE * scale;
+ UI_draw_roundbox_4fv_ex(
+ &(const rctf){
+ .xmin = -rad,
+ .xmax = rad,
+ .ymin = -rad,
+ .ymax = rad,
+ },
+ inner_color,
+ NULL,
+ 0.0f,
+ outline_color,
+ AXIS_RING_WIDTH,
+ rad);
+ GPU_matrix_pop();
+ }
- GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
- GPU_batch_uniform_4fv(sphere, "color", is_pos_color ? color_current : color_current_fade);
- GPU_batch_draw(sphere);
- GPU_matrix_pop();
+ /* Axis XYZ Character. */
+ if ((is_pos || is_highlight || (axis == axis_align)) && !is_aligned_back) {
+ float axis_str_width, axis_string_height;
+ char axis_str[3] = {'X' + axis, 0, 0};
+ if (!is_pos) {
+ axis_str[0] = '-';
+ axis_str[1] = 'X' + axis;
}
-
- /* Axis XYZ Character. */
- if (show_axis_char && (select == false)) {
-#ifdef USE_AXIS_FONT
- float axis_str_size[2] = {0};
- const char axis_str[2] = {'X' + axis, 0};
- BLF_width_and_height(font.id, axis_str, 2, &axis_str_size[0], &axis_str_size[1]);
-
- /* Calculate pixel aligned location, without this text draws fuzzy. */
- float v_final_px[3];
- mul_v3_m3v3(v_final_px, font.matrix_m3_invert, v_final);
- /* Center the test and pixel align, it's important to round once
- * otherwise the characters are noticeably not-centered.
- * If this wasn't an issue we could use #BLF_position to place the text. */
- v_final_px[0] = roundf(v_final_px[0] - (axis_str_size[0] / 2.0f));
- v_final_px[1] = roundf(v_final_px[1] - (axis_str_size[1] / 2.0f));
- mul_m3_v3(font.matrix_m3, v_final_px);
-
- immUnbindProgram();
-
- GPU_matrix_push();
- GPU_matrix_translate_3fv(v_final_px);
- GPU_matrix_mul(font.matrix);
-
- BLF_draw_ascii(font.id, axis_str, 2);
- GPU_blend(GPU_BLEND_ALPHA); /* XXX, blf disables */
- GPU_matrix_pop();
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-#else
- immUnbindProgram();
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- GPU_line_width(1.0f);
- float m3[3][3];
- copy_m3_m4(m3, gz->matrix_offset);
- immUniformColor4fv(axis_black);
- draw_xyz_wire(pos_id, m3, v_final, 1.0, axis);
- immUnbindProgram();
-#endif
+ BLF_width_and_height(font.id, axis_str, 3, &axis_str_width, &axis_string_height);
+
+ /* Calculate pixel-aligned location, without this text draws fuzzy. */
+ float v_final_px[3];
+ mul_v3_m3v3(v_final_px, font.matrix_m3_invert, v_final);
+ /* Center the text and pixel align, it's important to round once
+ * otherwise the characters are noticeably not-centered.
+ * If this wasn't an issue we could use #BLF_position to place the text. */
+ v_final_px[0] = roundf(v_final_px[0] - (axis_str_width * (is_pos ? 0.5f : 0.55f)));
+ v_final_px[1] = roundf(v_final_px[1] - (axis_string_height / 2.0f));
+ mul_m3_v3(font.matrix_m3, v_final_px);
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(v_final_px);
+ GPU_matrix_mul(font.matrix);
+ float text_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ if (!is_highlight) {
+ zero_v4(text_color);
+ text_color[3] = is_active ? 1.0f : 0.9f;
}
+ BLF_color4fv(font.id, text_color);
+ BLF_draw_ascii(font.id, axis_str, 2);
+ GPU_matrix_pop();
}
}
- GPU_matrix_pop();
- immUnbindProgram();
-
if (use_project_matrix) {
GPU_matrix_pop_projection();
}
-}
-
-static void axis3d_draw_intern(const bContext *C,
- wmGizmo *gz,
- const bool select,
- const bool highlight)
-{
- const float *color = highlight ? gz->color_hi : gz->color;
- float matrix_final[4][4];
- float matrix_unit[4][4];
-
- unit_m4(matrix_unit);
-
- WM_gizmo_calc_matrix_final_params(gz,
- &((struct WM_GizmoMatrixParams){
- .matrix_offset = matrix_unit,
- }),
- matrix_final);
-
- GPU_matrix_push();
- GPU_matrix_mul(matrix_final);
-
- struct AxisDrawInfo draw_info;
-#ifdef USE_AXIS_FONT
- if (select == false) {
- copy_m4_m4(draw_info.matrix_final, matrix_final);
- }
-#endif
-#ifdef USE_FADE_BACKGROUND
- if (select == false) {
- ED_view3d_background_color_get(CTX_data_scene(C), CTX_wm_view3d(C), draw_info.color_bg);
- }
-#else
- UNUSED_VARS(C);
-#endif
-
- GPU_blend(GPU_BLEND_ALPHA);
- axis_geom_draw(gz, color, select, &draw_info);
GPU_blend(GPU_BLEND_NONE);
+ BLF_disable(font.id, BLF_BOLD);
GPU_matrix_pop();
}
-static void gizmo_axis_draw(const bContext *C, wmGizmo *gz)
-{
- const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
- const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
-
- (void)is_modal;
-
- GPU_blend(GPU_BLEND_ALPHA);
- axis3d_draw_intern(C, gz, false, is_highlight);
- GPU_blend(GPU_BLEND_NONE);
-}
-
static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
{
float point_local[2] = {UNPACK2(mval)};
@@ -601,12 +367,19 @@ static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mv
return -1;
}
-static int gizmo_axis_cursor_get(wmGizmo *gz)
+static int gizmo_axis_cursor_get(wmGizmo *UNUSED(gz))
{
- if (gz->highlight_part > 0) {
- return WM_CURSOR_EDIT;
- }
- return WM_CURSOR_NSEW_SCROLL;
+ return WM_CURSOR_DEFAULT;
+}
+
+static void gizmo_axis_screen_bounds_get(bContext *C, wmGizmo *gz, rcti *r_bounding_box)
+{
+ ScrArea *area = CTX_wm_area(C);
+ const float rad = WIDGET_RADIUS;
+ r_bounding_box->xmin = gz->matrix_basis[3][0] + area->totrct.xmin - rad;
+ r_bounding_box->ymin = gz->matrix_basis[3][1] + area->totrct.ymin - rad;
+ r_bounding_box->xmax = r_bounding_box->xmin + rad;
+ r_bounding_box->ymax = r_bounding_box->ymin + rad;
}
void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt)
@@ -618,6 +391,7 @@ void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt)
gzt->draw = gizmo_axis_draw;
gzt->test_select = gizmo_axis_test_select;
gzt->cursor_get = gizmo_axis_cursor_get;
+ gzt->screen_bounds_get = gizmo_axis_screen_bounds_get;
gzt->struct_size = sizeof(wmGizmo);
}
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
index 3f07653fb2f..171cf721343 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
@@ -30,7 +30,6 @@
#include "UI_resources.h"
#include "WM_api.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
#include "view3d_intern.h" /* own include */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index f2e42cd1725..607ca110d0f 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -40,14 +40,11 @@
#include "DEG_depsgraph.h"
#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
-#include "ED_screen.h"
#include "ED_undo.h"
#include "UI_interface.h"
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 0770bac1313..344168e895b 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -24,7 +24,6 @@
#include <math.h>
#include <stdlib.h>
-#include "DNA_collection_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -36,7 +35,6 @@
#include "BKE_appdir.h"
#include "BKE_blender_copybuffer.h"
-#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -49,7 +47,6 @@
#include "ED_outliner.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "ED_transform.h"
#include "view3d_intern.h"
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 35ec4de5077..0605ea30806 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -596,7 +596,7 @@ static bool do_lasso_select_objects(ViewContext *vc,
}
for (base = vc->view_layer->object_bases.first; base; base = base->next) {
- if (BASE_SELECTABLE(v3d, base)) { /* use this to avoid un-needed lasso lookups */
+ if (BASE_SELECTABLE(v3d, base)) { /* Use this to avoid unnecessary lasso look-ups. */
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(
@@ -1447,7 +1447,7 @@ static const EnumPropertyItem *object_select_menu_enum_itemf(bContext *C,
int totitem = 0;
int i = 0;
- /* don't need context but avoid docgen using this */
+ /* Don't need context but avoid API doc-generation using this. */
if (C == NULL || object_mouse_select_menu_data[i].idname[0] == '\0') {
return DummyRNA_NULL_items;
}
@@ -2494,8 +2494,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
}
/* Pass-through allows tweaks
- * FINISHED to signal one operator worked
- * */
+ * FINISHED to signal one operator worked */
if (retval) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 148a0986c5c..cce9287679c 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -27,7 +27,6 @@
#include "DNA_object_types.h"
#include "BLI_array.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 2b7b8255068..a6a77ecd5f7 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -224,13 +224,11 @@ void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *region)
*/
void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
{
- float viewdist;
-
if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) {
return;
}
- viewdist = rv3d->dist;
+ float viewdist = rv3d->dist;
/* special exception for ortho camera (viewdist isnt used for perspective cameras) */
if (dist != 0.0f) {
@@ -248,7 +246,6 @@ bool ED_view3d_context_activate(bContext *C)
{
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = CTX_wm_area(C);
- ARegion *region;
/* area can be NULL when called from python */
if (area == NULL || area->spacetype != SPACE_VIEW3D) {
@@ -259,7 +256,7 @@ bool ED_view3d_context_activate(bContext *C)
return false;
}
- region = BKE_area_find_region_active_win(area);
+ ARegion *region = BKE_area_find_region_active_win(area);
if (region == NULL) {
return false;
}
@@ -282,9 +279,7 @@ void ED_view3d_clipping_calc_from_boundbox(float clip[4][4],
const BoundBox *bb,
const bool is_flip)
{
- int val;
-
- for (val = 0; val < 4; val++) {
+ for (int val = 0; val < 4; val++) {
normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
if (UNLIKELY(is_flip)) {
negate_v3(clip[val]);
@@ -752,14 +747,12 @@ bool ED_view3d_camera_lock_autokey(View3D *v3d,
static void view3d_boxview_clip(ScrArea *area)
{
- ARegion *region;
BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
float clip[6][4];
float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
- int val;
/* create bounding box */
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = region->regiondata;
@@ -794,7 +787,7 @@ static void view3d_boxview_clip(ScrArea *area)
}
}
- for (val = 0; val < 8; val++) {
+ for (int val = 0; val < 8; val++) {
if (ELEM(val, 0, 3, 4, 7)) {
bb->vec[val][0] = -x1 - ofs[0];
}
@@ -826,12 +819,12 @@ static void view3d_boxview_clip(ScrArea *area)
normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
/* then plane equations */
- for (val = 0; val < 6; val++) {
+ for (int val = 0; val < 6; val++) {
clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
}
/* create bounding box */
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = region->regiondata;
@@ -950,11 +943,10 @@ void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip)
{
ARegion *region_sync = NULL;
RegionView3D *rv3d = region->regiondata;
- short viewlock;
/* this function copies flags from the first of the 3 other quadview
* regions to the 2 other, so it assumes this is the region whose
* properties are always being edited, weak */
- viewlock = rv3d->viewlock;
+ short viewlock = rv3d->viewlock;
if ((viewlock & RV3D_LOCK_ROTATION) == 0) {
do_clip = (viewlock & RV3D_BOXCLIP) != 0;
@@ -1015,10 +1007,7 @@ void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip)
static float view_autodist_depth_margin(ARegion *region, const int mval[2], int margin)
{
- ViewDepths depth_temp = {0};
rcti rect;
- float depth_close;
-
if (margin == 0) {
/* Get Z Depths, needed for perspective, nice for ortho */
rect.xmin = mval[0];
@@ -1030,8 +1019,9 @@ static float view_autodist_depth_margin(ARegion *region, const int mval[2], int
BLI_rcti_init_pt_radius(&rect, mval, margin);
}
+ ViewDepths depth_temp = {0};
view3d_update_depths_rect(region, &depth_temp, &rect);
- depth_close = view3d_depth_near(&depth_temp);
+ float depth_close = view3d_depth_near(&depth_temp);
MEM_SAFE_FREE(depth_temp.depths);
return depth_close;
}
@@ -1053,14 +1043,13 @@ bool ED_view3d_autodist(Depsgraph *depsgraph,
{
float depth_close;
int margin_arr[] = {0, 2, 4};
- int i;
bool depth_ok = false;
/* Get Z Depths, needed for perspective, nice for ortho */
ED_view3d_draw_depth(depsgraph, region, v3d, alphaoverride);
/* Attempt with low margin's first */
- i = 0;
+ int i = 0;
do {
depth_close = view_autodist_depth_margin(region, mval, margin_arr[i++] * U.pixelsize);
depth_ok = (depth_close != FLT_MAX);
@@ -1104,9 +1093,8 @@ bool ED_view3d_autodist_simple(ARegion *region,
int margin,
const float *force_depth)
{
- float depth;
-
/* Get Z Depths, needed for perspective, nice for ortho */
+ float depth;
if (force_depth) {
depth = *force_depth;
}
@@ -1237,7 +1225,6 @@ float ED_view3d_radius_to_dist(const View3D *v3d,
}
else {
float lens, sensor_size, zoom;
- float angle;
if (persp == RV3D_CAMOB) {
CameraParams params;
@@ -1259,7 +1246,7 @@ float ED_view3d_radius_to_dist(const View3D *v3d,
zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
}
- angle = focallength_to_fov(lens, sensor_size);
+ float angle = focallength_to_fov(lens, sensor_size);
/* zoom influences lens, correct this by scaling the angle as a distance
* (by the zoom-level) */
@@ -1319,14 +1306,13 @@ float ED_view3d_offset_distance(const float mat[4][4],
{
float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
- float dist;
mul_m4_v4(mat, pos);
add_v3_v3(pos, ofs);
mul_m4_v4(mat, dir);
normalize_v3(dir);
- dist = dot_v3v3(pos, dir);
+ float dist = dot_v3v3(pos, dir);
if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
dist = fallback_dist;
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 9d947384bf0..5c0ca1582a6 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -142,7 +142,7 @@ void ED_view3d_smooth_view_ex(
/* initialize sms */
view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
- /* if smoothview runs multiple times... */
+ /* If smooth-view runs multiple times. */
if (rv3d->sms == NULL) {
view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
}
@@ -396,7 +396,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b
/* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
* when switching camera in quad-view the other ortho views would zoom & reset.
*
- * For now only redraw all regions when smoothview finishes.
+ * For now only redraw all regions when smooth-view finishes.
*/
if (step >= 1.0f) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
@@ -423,7 +423,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w
}
/**
- * Apply the smoothview immediately, use when we need to start a new view operation.
+ * Apply the smooth-view immediately, use when we need to start a new view operation.
* (so we don't end up half-applying a view operation when pressing keys quickly).
*/
void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 5b42f221c80..cbd65e3175d 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -48,7 +48,7 @@
#include "ED_space_api.h"
#include "ED_transform_snap_object_context.h"
-#include "PIL_time.h" /* smoothview */
+#include "PIL_time.h" /* Smooth-view. */
#include "UI_interface.h"
#include "UI_resources.h"
@@ -872,7 +872,7 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
/* delta time */
t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
- /* reduce the veolocity, if JUMP wasn't hold for long enough */
+ /* Reduce the velocity, if JUMP wasn't hold for long enough. */
t = min_ff(t, JUMP_TIME_MAX);
walk->speed_jump = JUMP_SPEED_MIN +
t * (JUMP_SPEED_MAX - JUMP_SPEED_MIN) / JUMP_TIME_MAX;
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index faed8abb202..b0bc5c6abda 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -55,6 +55,7 @@ set(SRC
transform_convert_nla.c
transform_convert_node.c
transform_convert_object.c
+ transform_convert_object_texspace.c
transform_convert_paintcurve.c
transform_convert_particle.c
transform_convert_sculpt.c
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 2a7c247ff2b..2fbcbe22349 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -135,7 +135,7 @@ void setTransformViewAspect(TransInfo *t, float r_aspect[3])
}
}
else if (t->spacetype == SPACE_GRAPH) {
- /* depemds on context of usage */
+ /* Depends on context of usage. */
}
}
@@ -440,7 +440,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
}
else {
/* Do we need more refined tags? */
- if (t->flag & T_POSE) {
+ if (t->options & CTX_POSE_BONE) {
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
else {
@@ -471,7 +471,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_SEQ) {
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, NULL);
- /* Keyframes on strips has been moved, so make sure related editos are informed. */
+ /* Key-frames on strips has been moved, so make sure related editors are informed. */
WM_event_add_notifier(C, NC_ANIMATION, NULL);
}
else if (t->spacetype == SPACE_IMAGE) {
@@ -484,7 +484,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
wmWindow *window = CTX_wm_window(C);
WM_paint_cursor_tag_redraw(window, t->region);
}
- else if (t->flag & T_CURSOR) {
+ else if (t->options & CTX_CURSOR) {
ED_area_tag_redraw(t->area);
}
else {
@@ -695,6 +695,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
{TFM_MODAL_AUTOCONSTRAINT, "AUTOCONSTRAIN", 0, "Automatic Constraint", ""},
{TFM_MODAL_AUTOCONSTRAINTPLANE, "AUTOCONSTRAINPLANE", 0, "Automatic Constraint Plane", ""},
+ {TFM_MODAL_PRECISION, "PRECISION", 0, "Precision Mode", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -806,8 +807,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
const int modifiers_prev = t->modifiers;
const int mode_prev = t->mode;
- t->redraw |= handleMouseInput(t, &t->mouse, event);
-
/* Handle modal numinput events first, if already activated. */
if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && hasNumInput(&t->num) &&
handleNumInput(t->context, &(t->num), event)) {
@@ -895,7 +894,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
case TFM_MODAL_ROTATE:
/* only switch when... */
- if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
+ if (!(t->options & CTX_TEXTURE_SPACE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
if (transform_mode_is_changeable(t->mode)) {
restoreTransObjects(t);
resetTransModal(t);
@@ -1069,7 +1068,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
t->modifiers &= ~(MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE);
}
else {
- if (t->flag & T_CAMERA) {
+ if (t->options & CTX_CAMERA) {
/* Exception for switching to dolly, or trackball, in camera view. */
if (t->mode == TFM_TRANSLATION) {
setLocalConstraint(t, (CON_AXIS2), TIP_("along local Z"));
@@ -1095,6 +1094,19 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
break;
+ case TFM_MODAL_PRECISION:
+ if (event->prevval == KM_PRESS) {
+ t->modifiers |= MOD_PRECISION;
+ /* Shift is modifier for higher precision transform. */
+ t->mouse.precision = 1;
+ t->redraw |= TREDRAW_HARD;
+ }
+ else if (event->prevval == KM_RELEASE) {
+ t->modifiers &= ~MOD_PRECISION;
+ t->mouse.precision = 0;
+ t->redraw |= TREDRAW_HARD;
+ }
+ break;
/* Those two are only handled in transform's own handler, see T44634! */
case TFM_MODAL_EDGESLIDE_UP:
case TFM_MODAL_EDGESLIDE_DOWN:
@@ -1249,7 +1261,7 @@ bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], floa
createTransData(C, t); /* make TransData structs from selection */
- t->around = centerMode; /* override userdefined mode */
+ t->around = centerMode; /* override user-defined mode. */
if (t->data_len_all == 0) {
success = false;
@@ -1382,7 +1394,7 @@ static void drawTransformPixel(const struct bContext *C, ARegion *region, void *
*/
if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) {
if (region == t->region) {
- if (t->flag & (T_OBJECT | T_POSE)) {
+ if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) {
drawAutoKeyWarning(t, region);
}
@@ -1652,7 +1664,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
if ((prop = RNA_struct_find_property(op->ptr, "texture_space")) &&
RNA_property_is_set(op->ptr, prop)) {
if (RNA_property_boolean_get(op->ptr, prop)) {
- options |= CTX_TEXTURE;
+ options |= CTX_TEXTURE_SPACE;
}
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index fff7d47cc5b..24335b6b6b7 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -36,6 +36,11 @@
#include "transform_data.h"
+/* use node center for transform instead of upper-left corner.
+ * disabled since it makes absolute snapping not work so nicely
+ */
+// #define USE_NODE_CENTER
+
/* -------------------------------------------------------------------- */
/** \name Types/
* \{ */
@@ -60,6 +65,134 @@ struct wmKeyMap;
struct wmOperator;
struct wmTimer;
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Enums and Flags
+ * \{ */
+
+/** #TransInfo.options */
+typedef enum {
+ CTX_NONE = 0,
+
+ /* These are similar to TransInfo::data_type. */
+ CTX_CAMERA = (1 << 0),
+ CTX_CURSOR = (1 << 1),
+ CTX_EDGE_DATA = (1 << 2),
+ CTX_GPENCIL_STROKES = (1 << 3),
+ CTX_MASK = (1 << 4),
+ CTX_MOVIECLIP = (1 << 5),
+ CTX_OBJECT = (1 << 6),
+ CTX_PAINT_CURVE = (1 << 7),
+ CTX_POSE_BONE = (1 << 8),
+ CTX_TEXTURE_SPACE = (1 << 9),
+
+ CTX_NO_PET = (1 << 10),
+ CTX_NO_MIRROR = (1 << 11),
+ CTX_AUTOCONFIRM = (1 << 12),
+ /** When transforming object's, adjust the object data so it stays in the same place. */
+ CTX_OBMODE_XFORM_OBDATA = (1 << 13),
+ /** Transform object parents without moving their children. */
+ CTX_OBMODE_XFORM_SKIP_CHILDREN = (1 << 14),
+} eTContext;
+
+/** #TransInfo.flag */
+typedef enum {
+ /** \note We could remove 'T_EDIT' and use 'obedit_type', for now ensure they're in sync. */
+ T_EDIT = 1 << 0,
+ /** Transform points, having no rotation/scale. */
+ T_POINTS = 1 << 1,
+ /** restrictions flags */
+ T_NO_CONSTRAINT = 1 << 2,
+ T_NULL_ONE = 1 << 3,
+ T_NO_ZERO = 1 << 4,
+ T_ALL_RESTRICTIONS = T_NO_CONSTRAINT | T_NULL_ONE | T_NO_ZERO,
+
+ T_PROP_EDIT = 1 << 5,
+ T_PROP_CONNECTED = 1 << 6,
+ T_PROP_PROJECTED = 1 << 7,
+ T_PROP_EDIT_ALL = T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED,
+
+ T_V3D_ALIGN = 1 << 8,
+ /** For 2D views such as UV or f-curve. */
+ T_2D_EDIT = 1 << 9,
+ T_CLIP_UV = 1 << 10,
+
+ /** Auto-IK is on. */
+ T_AUTOIK = 1 << 11,
+
+ /** Don't use mirror even if the data-block option is set. */
+ T_NO_MIRROR = 1 << 12,
+
+ /** To indicate that the value set in the `value` parameter is the final
+ * value of the transformation, modified only by the constrain. */
+ T_INPUT_IS_VALUES_FINAL = 1 << 13,
+
+ /** To specify if we save back settings at the end. */
+ T_MODAL = 1 << 14,
+
+ /** No re-topology (projection). */
+ T_NO_PROJECT = 1 << 15,
+
+ T_RELEASE_CONFIRM = 1 << 16,
+
+ /** Alternative transformation. used to add offset to tracking markers. */
+ T_ALT_TRANSFORM = 1 << 17,
+
+ /** #TransInfo.center has been set, don't change it. */
+ T_OVERRIDE_CENTER = 1 << 18,
+
+ T_MODAL_CURSOR_SET = 1 << 19,
+
+ T_CLNOR_REBUILD = 1 << 20,
+
+ /** Merges unselected into selected after transforming (runs after transforming). */
+ T_AUTOMERGE = 1 << 21,
+ /** Runs auto-merge & splits. */
+ T_AUTOSPLIT = 1 << 22,
+} eTFlag;
+
+/** #TransInfo.modifiers */
+typedef enum {
+ MOD_CONSTRAINT_SELECT = 1 << 0,
+ MOD_PRECISION = 1 << 1,
+ MOD_SNAP = 1 << 2,
+ MOD_SNAP_INVERT = 1 << 3,
+ MOD_CONSTRAINT_PLANE = 1 << 4,
+} eTModifier;
+
+/** #TransSnap.status */
+typedef enum {
+ SNAP_FORCED = 1 << 0,
+ TARGET_INIT = 1 << 1,
+ /* Special flag for snap to grid. */
+ TARGET_GRID_INIT = 1 << 2,
+ POINT_INIT = 1 << 3,
+ MULTI_POINTS = 1 << 4,
+} eTSnap;
+
+/** #TransCon.mode, #TransInfo.con.mode */
+typedef enum {
+ /** When set constraints are in use. */
+ CON_APPLY = 1 << 0,
+ /** These are only used for modal execution. */
+ CON_AXIS0 = 1 << 1,
+ CON_AXIS1 = 1 << 2,
+ CON_AXIS2 = 1 << 3,
+ CON_SELECT = 1 << 4,
+ /** Does not reorient vector to face viewport when on. */
+ CON_NOFLIP = 1 << 5,
+ CON_USER = 1 << 6,
+} eTConstraint;
+
+/** #TransInfo.state */
+typedef enum {
+ TRANS_STARTING = 0,
+ TRANS_RUNNING = 1,
+ TRANS_CONFIRM = 2,
+ TRANS_CANCEL = 3,
+} eTState;
+
/** #TransInfo.redraw */
typedef enum {
TREDRAW_NOTHING = 0,
@@ -67,6 +200,97 @@ typedef enum {
TREDRAW_SOFT = 2,
} eRedrawFlag;
+/** #TransInfo.helpline */
+typedef enum {
+ HLP_NONE = 0,
+ HLP_SPRING = 1,
+ HLP_ANGLE = 2,
+ HLP_HARROW = 3,
+ HLP_VARROW = 4,
+ HLP_CARROW = 5,
+ HLP_TRACKBALL = 6,
+} eTHelpline;
+
+typedef enum {
+ TC_NONE = 0,
+ TC_ACTION_DATA,
+ TC_POSE,
+ TC_ARMATURE_VERTS,
+ TC_CURSOR_IMAGE,
+ TC_CURSOR_VIEW3D,
+ TC_CURVE_VERTS,
+ TC_GRAPH_EDIT_DATA,
+ TC_GPENCIL,
+ TC_LATTICE_VERTS,
+ TC_MASKING_DATA,
+ TC_MBALL_VERTS,
+ TC_MESH_VERTS,
+ TC_MESH_EDGES,
+ TC_MESH_SKIN,
+ TC_MESH_UV,
+ TC_NLA_DATA,
+ TC_NODE_DATA,
+ TC_OBJECT,
+ TC_OBJECT_TEXSPACE,
+ TC_PAINT_CURVE_VERTS,
+ TC_PARTICLE_VERTS,
+ TC_SCULPT,
+ TC_SEQ_DATA,
+ TC_TRACKING_DATA,
+} eTConvertType;
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Keymap Modal Items
+ *
+ * \note these values are saved in key-map files, do not change then but just add new ones.
+ * \{ */
+
+enum {
+ TFM_MODAL_CANCEL = 1,
+ TFM_MODAL_CONFIRM = 2,
+ TFM_MODAL_TRANSLATE = 3,
+ TFM_MODAL_ROTATE = 4,
+ TFM_MODAL_RESIZE = 5,
+ TFM_MODAL_SNAP_INV_ON = 6,
+ TFM_MODAL_SNAP_INV_OFF = 7,
+ TFM_MODAL_SNAP_TOGGLE = 8,
+ TFM_MODAL_AXIS_X = 9,
+ TFM_MODAL_AXIS_Y = 10,
+ TFM_MODAL_AXIS_Z = 11,
+ TFM_MODAL_PLANE_X = 12,
+ TFM_MODAL_PLANE_Y = 13,
+ TFM_MODAL_PLANE_Z = 14,
+ TFM_MODAL_CONS_OFF = 15,
+ TFM_MODAL_ADD_SNAP = 16,
+ TFM_MODAL_REMOVE_SNAP = 17,
+
+ /* 18 and 19 used by number-input, defined in `ED_numinput.h`. */
+ // NUM_MODAL_INCREMENT_UP = 18,
+ // NUM_MODAL_INCREMENT_DOWN = 19,
+
+ TFM_MODAL_PROPSIZE_UP = 20,
+ TFM_MODAL_PROPSIZE_DOWN = 21,
+ TFM_MODAL_AUTOIK_LEN_INC = 22,
+ TFM_MODAL_AUTOIK_LEN_DEC = 23,
+
+ TFM_MODAL_EDGESLIDE_UP = 24,
+ TFM_MODAL_EDGESLIDE_DOWN = 25,
+
+ /** For analog input, like track-pad. */
+ TFM_MODAL_PROPSIZE = 26,
+ /** Node editor insert offset (also called auto-offset) direction toggle. */
+ TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27,
+
+ TFM_MODAL_AUTOCONSTRAINT = 28,
+ TFM_MODAL_AUTOCONSTRAINTPLANE = 29,
+
+ TFM_MODAL_PRECISION = 30,
+};
+
+/** \} */
+
typedef struct TransSnapPoint {
struct TransSnapPoint *next, *prev;
float co[3];
@@ -82,13 +306,14 @@ typedef struct TransSnap {
bool snap_self;
bool peel;
bool use_backface_culling;
- char status;
+ eTSnap status;
/* Snapped Element Type (currently for objects only). */
char snapElem;
/** snapping from this point (in global-space). */
float snapPoint[3];
/** to this point (in global-space). */
float snapTarget[3];
+ float snapTargetGrid[3];
float snapNormal[3];
char snapNodeBorder;
ListBase points;
@@ -120,7 +345,7 @@ typedef struct TransCon {
* the one in #TransInfo is not guarantee to stay the same (Rotates change it). */
int imval[2];
/** Mode flags of the constraint. */
- int mode;
+ eTConstraint mode;
void (*drawExtra)(struct TransInfo *t);
/* Note: if 'tc' is NULL, 'td' must also be NULL.
@@ -266,37 +491,45 @@ typedef struct TransInfo {
TransDataContainer *data_container;
int data_container_len;
- /** #eTransConvertType
- * TODO: It should be a member of #TransDataContainer. */
- int data_type;
-
/** Combine length of all #TransDataContainer.data_len
* Use to check if nothing is selected or if we have a single selection. */
int data_len_all;
- /** Current mode. */
- int mode;
+ /** TODO: It should be a member of #TransDataContainer. */
+ eTConvertType data_type;
+
+ /** Current context/options for transform. */
+ eTContext options;
/** Generic flags for special behaviors. */
- int flag;
+ eTFlag flag;
/** Special modifiers, by function, not key. */
- int modifiers;
+ eTModifier modifiers;
/** Current state (running, canceled. */
- short state;
- /** Current context/options for transform. */
- int options;
+ eTState state;
+ /** Redraw flag. */
+ eRedrawFlag redraw;
+ /** Choice of custom cursor with or without a help line from the gizmo to the mouse position. */
+ eTHelpline helpline;
+ /** Current mode. */
+ eTfmMode mode;
+
+ /** Main transform mode function. */
void (*transform)(struct TransInfo *, const int[2]);
- /** Transform function pointer. */
+ /* Event handler function that determines whether the viewport needs to be redrawn. */
eRedrawFlag (*handleEvent)(struct TransInfo *, const struct wmEvent *);
- /* event handler function pointer RETURN 1 if redraw is needed */
- /** transformed constraint. */
+
+ /** Constraint Data. */
TransCon con;
+
+ /** Snap Data. */
TransSnap tsnap;
- /** numerical input. */
+
+ /** Numerical input. */
NumInput num;
- /** mouse input. */
+
+ /** Mouse input. */
MouseInput mouse;
- /** redraw flag. */
- eRedrawFlag redraw;
+
/** proportional circle radius. */
float prop_size;
/** proportional falloff text. */
@@ -310,9 +543,6 @@ typedef struct TransInfo {
float center_global[3];
/** center in screen coordinates. */
float center2d[2];
- /* Lazy initialize center data for when we need other center values.
- * V3D_AROUND_ACTIVE + 1 (static assert checks this) */
- TransCenterData center_cache[5];
/** maximum index on the input vector. */
short idx_max;
/** Snapping Gears. */
@@ -333,8 +563,6 @@ typedef struct TransInfo {
short around;
/** space-type where transforming is. */
char spacetype;
- /** Choice of custom cursor with or without a help line from the gizmo to the mouse position. */
- char helpline;
/** Avoid looking inside #TransDataContainer.obedit. */
short obedit_type;
@@ -422,178 +650,6 @@ typedef struct TransInfo {
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Flags
- * \{ */
-
-/** #TransInfo.state */
-enum {
- TRANS_STARTING = 0,
- TRANS_RUNNING = 1,
- TRANS_CONFIRM = 2,
- TRANS_CANCEL = 3,
-};
-
-/** #TransInfo.flag */
-enum {
- T_OBJECT = 1 << 0,
- /** \note We could remove 'T_EDIT' and use 'obedit_type', for now ensure they're in sync. */
- T_EDIT = 1 << 1,
- T_POSE = 1 << 2,
- T_TEXTURE = 1 << 3,
- /** Transforming the 3d view. */
- T_CAMERA = 1 << 4,
- /** Transforming the 3D cursor. */
- T_CURSOR = 1 << 5,
- /** Transform points, having no rotation/scale. */
- T_POINTS = 1 << 6,
- /** restrictions flags */
- T_NO_CONSTRAINT = 1 << 7,
- T_NULL_ONE = 1 << 8,
- T_NO_ZERO = 1 << 9,
- T_ALL_RESTRICTIONS = T_NO_CONSTRAINT | T_NULL_ONE | T_NO_ZERO,
-
- T_PROP_EDIT = 1 << 10,
- T_PROP_CONNECTED = 1 << 11,
- T_PROP_PROJECTED = 1 << 12,
- T_PROP_EDIT_ALL = T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED,
-
- T_V3D_ALIGN = 1 << 13,
- /** For 2D views such as UV or f-curve. */
- T_2D_EDIT = 1 << 14,
- T_CLIP_UV = 1 << 15,
-
- /** Auto-IK is on. */
- T_AUTOIK = 1 << 16,
-
- /** Don't use mirror even if the data-block option is set. */
- T_NO_MIRROR = 1 << 17,
-
- /** To indicate that the value set in the `value` parameter is the final
- * value of the transformation, modified only by the constrain. */
- T_INPUT_IS_VALUES_FINAL = 1 << 18,
-
- /** To specify if we save back settings at the end. */
- T_MODAL = 1 << 19,
-
- /** No re-topology (projection). */
- T_NO_PROJECT = 1 << 20,
-
- T_RELEASE_CONFIRM = 1 << 21,
-
- /** Alternative transformation. used to add offset to tracking markers. */
- T_ALT_TRANSFORM = 1 << 22,
-
- /** #TransInfo.center has been set, don't change it. */
- T_OVERRIDE_CENTER = 1 << 23,
-
- T_MODAL_CURSOR_SET = 1 << 24,
-
- T_CLNOR_REBUILD = 1 << 25,
-
- /** Merges unselected into selected after transforming (runs after transforming). */
- T_AUTOMERGE = 1 << 26,
- /** Runs auto-merge & splits. */
- T_AUTOSPLIT = 1 << 27,
-};
-
-/** #TransInfo.modifiers */
-enum {
- MOD_CONSTRAINT_SELECT = 1 << 0,
- MOD_PRECISION = 1 << 1,
- MOD_SNAP = 1 << 2,
- MOD_SNAP_INVERT = 1 << 3,
- MOD_CONSTRAINT_PLANE = 1 << 4,
-};
-
-/* use node center for transform instead of upper-left corner.
- * disabled since it makes absolute snapping not work so nicely
- */
-// #define USE_NODE_CENTER
-
-/** #TransInfo.helpline */
-enum {
- HLP_NONE = 0,
- HLP_SPRING = 1,
- HLP_ANGLE = 2,
- HLP_HARROW = 3,
- HLP_VARROW = 4,
- HLP_CARROW = 5,
- HLP_TRACKBALL = 6,
-};
-
-/** #TransCon.mode, #TransInfo.con.mode */
-enum {
- /** When set constraints are in use. */
- CON_APPLY = 1 << 0,
- /** These are only used for modal execution. */
- CON_AXIS0 = 1 << 1,
- CON_AXIS1 = 1 << 2,
- CON_AXIS2 = 1 << 3,
- CON_SELECT = 1 << 4,
- /** Does not reorient vector to face viewport when on. */
- CON_NOFLIP = 1 << 5,
- CON_USER = 1 << 6,
-};
-
-/** #TransSnap.status */
-enum {
- SNAP_FORCED = 1 << 0,
- TARGET_INIT = 1 << 1,
- POINT_INIT = 1 << 2,
- MULTI_POINTS = 1 << 3,
-};
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Keymap Modal Items
- *
- * \note these values are saved in key-map files, do not change then but just add new ones.
- * \{ */
-
-enum {
- TFM_MODAL_CANCEL = 1,
- TFM_MODAL_CONFIRM = 2,
- TFM_MODAL_TRANSLATE = 3,
- TFM_MODAL_ROTATE = 4,
- TFM_MODAL_RESIZE = 5,
- TFM_MODAL_SNAP_INV_ON = 6,
- TFM_MODAL_SNAP_INV_OFF = 7,
- TFM_MODAL_SNAP_TOGGLE = 8,
- TFM_MODAL_AXIS_X = 9,
- TFM_MODAL_AXIS_Y = 10,
- TFM_MODAL_AXIS_Z = 11,
- TFM_MODAL_PLANE_X = 12,
- TFM_MODAL_PLANE_Y = 13,
- TFM_MODAL_PLANE_Z = 14,
- TFM_MODAL_CONS_OFF = 15,
- TFM_MODAL_ADD_SNAP = 16,
- TFM_MODAL_REMOVE_SNAP = 17,
-
- /* 18 and 19 used by number-input, defined in `ED_numinput.h`. */
- // NUM_MODAL_INCREMENT_UP = 18,
- // NUM_MODAL_INCREMENT_DOWN = 19,
-
- TFM_MODAL_PROPSIZE_UP = 20,
- TFM_MODAL_PROPSIZE_DOWN = 21,
- TFM_MODAL_AUTOIK_LEN_INC = 22,
- TFM_MODAL_AUTOIK_LEN_DEC = 23,
-
- TFM_MODAL_EDGESLIDE_UP = 24,
- TFM_MODAL_EDGESLIDE_DOWN = 25,
-
- /** For analog input, like track-pad. */
- TFM_MODAL_PROPSIZE = 26,
- /** Node editor insert offset (also called auto-offset) direction toggle. */
- TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27,
-
- TFM_MODAL_AUTOCONSTRAINT = 28,
- TFM_MODAL_AUTOCONSTRAINTPLANE = 29,
-};
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Public Transform API
* \{ */
@@ -666,9 +722,6 @@ typedef enum {
void initMouseInput(
TransInfo *t, MouseInput *mi, const float center[2], const int mval[2], const bool precision);
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
-eRedrawFlag handleMouseInput(struct TransInfo *t,
- struct MouseInput *mi,
- const struct wmEvent *event);
void applyMouseInput(struct TransInfo *t,
struct MouseInput *mi,
const int mval[2],
@@ -684,10 +737,6 @@ void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float val
/** \name Generics
* \{ */
-void initTransDataContainers_FromObjectData(TransInfo *t,
- struct Object *obact,
- struct Object **objects,
- uint objects_len);
void initTransInfo(struct bContext *C,
TransInfo *t,
struct wmOperator *op,
@@ -709,7 +758,6 @@ void recalcData(TransInfo *t);
void calculateCenter2D(TransInfo *t);
void calculateCenterLocal(TransInfo *t, const float center_global[3]);
-const TransCenterData *transformCenter_from_type(TransInfo *t, int around);
void calculateCenter(TransInfo *t);
/* API functions for getting center points */
@@ -724,6 +772,8 @@ void calculatePropRatio(TransInfo *t);
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot);
+struct Object *transform_object_deform_pose_armature_get(const TransInfo *t, struct Object *ob);
+
void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
/* TODO. transform_query.c */
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 2ac7e41a7c9..1f589a830fc 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -58,6 +58,10 @@
static void drawObjectConstraint(TransInfo *t);
+/* -------------------------------------------------------------------- */
+/** \name Internal Utilities
+ * \{ */
+
static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3])
{
unit_m3(r_pmtx);
@@ -380,14 +384,13 @@ static void planeProjection(const TransInfo *t, const float in[3], float out[3])
add_v3_v3v3(out, in, vec);
}
-/*
+/**
* Generic callback for constant spatial constraints applied to linear motion
*
- * The IN vector in projected into the constrained space and then further
+ * The `in` vector in projected into the constrained space and then further
* projected along the view vector.
* (in perspective mode, the view vector is relative to the position on screen)
*/
-
static void applyAxisConstraintVec(
TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, const float in[3], float out[3])
{
@@ -459,17 +462,16 @@ static void applyAxisConstraintVec(
}
}
-/*
+/**
* Generic callback for object based spatial constraints applied to linear motion
*
* At first, the following is applied without orientation
* The IN vector in projected into the constrained space and then further
* projected along the view vector.
- * (in perspective mode, the view vector is relative to the position on screen)
+ * (in perspective mode, the view vector is relative to the position on screen).
*
* Further down, that vector is mapped to each data's space.
*/
-
static void applyObjectConstraintVec(
TransInfo *t, TransDataContainer *tc, TransData *td, const float in[3], float out[3])
{
@@ -489,10 +491,9 @@ static void applyObjectConstraintVec(
}
}
-/*
- * Generic callback for constant spatial constraints applied to resize motion
+/**
+ * Generic callback for constant spatial constraints applied to resize motion.
*/
-
static void applyAxisConstraintSize(TransInfo *t,
TransDataContainer *UNUSED(tc),
TransData *td,
@@ -516,10 +517,9 @@ static void applyAxisConstraintSize(TransInfo *t,
}
}
-/*
- * Callback for object based spatial constraints applied to resize motion
+/**
+ * Callback for object based spatial constraints applied to resize motion.
*/
-
static void applyObjectConstraintSize(TransInfo *t,
TransDataContainer *tc,
TransData *td,
@@ -549,10 +549,10 @@ static void applyObjectConstraintSize(TransInfo *t,
}
}
-static void constraints_rotation_imp(TransInfo *t,
- float axismtx[3][3],
- float r_vec[3],
- float *r_angle)
+static void constraints_rotation_impl(TransInfo *t,
+ float axismtx[3][3],
+ float r_vec[3],
+ float *r_angle)
{
BLI_assert(t->con.mode & CON_APPLY);
int mode = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
@@ -581,15 +581,15 @@ static void constraints_rotation_imp(TransInfo *t,
}
}
-/*
+/**
* Generic callback for constant spatial constraints applied to rotations
*
- * The rotation axis is copied into VEC.
+ * The rotation axis is copied into `vec`.
*
* In the case of single axis constraints, the rotation axis is directly the one constrained to.
* For planar constraints (2 axis), the rotation axis is the normal of the plane.
*
- * The following only applies when CON_NOFLIP is not set.
+ * The following only applies when #CON_NOFLIP is not set.
* The vector is then modified to always point away from the screen (in global space)
* This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
@@ -598,19 +598,19 @@ static void applyAxisConstraintRot(
TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, float vec[3], float *angle)
{
if (!td && t->con.mode & CON_APPLY) {
- constraints_rotation_imp(t, t->spacemtx, vec, angle);
+ constraints_rotation_impl(t, t->spacemtx, vec, angle);
}
}
-/*
+/**
* Callback for object based spatial constraints applied to rotations
*
- * The rotation axis is copied into VEC.
+ * The rotation axis is copied into `vec`.
*
* In the case of single axis constraints, the rotation axis is directly the one constrained to.
* For planar constraints (2 axis), the rotation axis is the normal of the plane.
*
- * The following only applies when CON_NOFLIP is not set.
+ * The following only applies when #CON_NOFLIP is not set.
* The vector is then modified to always point away from the screen (in global space)
* This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
@@ -637,11 +637,15 @@ static void applyObjectConstraintRot(
axismtx = td->axismtx;
}
- constraints_rotation_imp(t, axismtx, vec, angle);
+ constraints_rotation_impl(t, axismtx, vec, angle);
}
}
-/*--------------------- INTERNAL SETUP CALLS ------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Setup Calls
+ * \{ */
void setConstraint(TransInfo *t, int mode, const char text[])
{
@@ -676,7 +680,7 @@ void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[])
void setLocalConstraint(TransInfo *t, int mode, const char text[])
{
- if (t->flag & T_EDIT) {
+ if ((t->flag & T_EDIT) || t->data_len_all == 1) {
/* Although in edit-mode each object has its local space, use the
* orientation of the active object. */
setConstraint(t, mode, text);
@@ -686,10 +690,10 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[])
}
}
-/*
+/**
* Set the constraint according to the user defined orientation
*
- * ftext is a format string passed to BLI_snprintf. It will add the name of
+ * `ftext` is a format string passed to #BLI_snprintf. It will add the name of
* the orientation where %s is (logically).
*/
void setUserConstraint(TransInfo *t, int mode, const char ftext[])
@@ -704,40 +708,35 @@ void setUserConstraint(TransInfo *t, int mode, const char ftext[])
const char *spacename = transform_orientations_spacename_get(t, orientation);
BLI_snprintf(text, sizeof(text), ftext, spacename);
- if (t->modifiers & (MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE)) {
- /* Force the orientation of the active object.
- * Although possible, it is not convenient to use the local or axis constraint
- * with the modifier to select constraint.
- * This also follows the convention of older versions. */
- setConstraint(t, mode, text);
- }
- else {
- switch (orientation) {
- case V3D_ORIENT_LOCAL:
- setLocalConstraint(t, mode, text);
- break;
- case V3D_ORIENT_NORMAL:
- if (checkUseAxisMatrix(t)) {
- setAxisMatrixConstraint(t, mode, text);
- break;
- }
- ATTR_FALLTHROUGH;
- case V3D_ORIENT_GLOBAL:
- case V3D_ORIENT_VIEW:
- case V3D_ORIENT_CURSOR:
- case V3D_ORIENT_GIMBAL:
- case V3D_ORIENT_CUSTOM_MATRIX:
- case V3D_ORIENT_CUSTOM:
- default: {
- setConstraint(t, mode, text);
+ switch (orientation) {
+ case V3D_ORIENT_LOCAL:
+ setLocalConstraint(t, mode, text);
+ break;
+ case V3D_ORIENT_NORMAL:
+ if (checkUseAxisMatrix(t)) {
+ setAxisMatrixConstraint(t, mode, text);
break;
}
+ ATTR_FALLTHROUGH;
+ case V3D_ORIENT_GLOBAL:
+ case V3D_ORIENT_VIEW:
+ case V3D_ORIENT_CURSOR:
+ case V3D_ORIENT_GIMBAL:
+ case V3D_ORIENT_CUSTOM_MATRIX:
+ case V3D_ORIENT_CUSTOM:
+ default: {
+ setConstraint(t, mode, text);
+ break;
}
}
t->con.mode |= CON_USER;
}
-/*----------------- DRAWING CONSTRAINTS -------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Drawing Constraints
+ * \{ */
void drawConstraint(TransInfo *t)
{
@@ -915,7 +914,7 @@ static void drawObjectConstraint(TransInfo *t)
mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx);
axismtx = tmp_axismtx;
}
- else if (t->flag & T_POSE) {
+ else if (t->options & CTX_POSE_BONE) {
mul_v3_m4v3(co, tc->mat, td->center);
axismtx = td->axismtx;
}
@@ -938,7 +937,11 @@ static void drawObjectConstraint(TransInfo *t)
}
}
-/*--------------------- START / STOP CONSTRAINTS ---------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Start / Stop Constraints
+ * \{ */
void startConstraint(TransInfo *t)
{
@@ -959,7 +962,11 @@ void stopConstraint(TransInfo *t)
t->num.idx_max = t->idx_max;
}
-/*------------------------- MMB Select -------------------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Middle Mouse Button Select
+ * \{ */
void initSelectConstraint(TransInfo *t)
{
@@ -1106,7 +1113,11 @@ void setNearestAxis(TransInfo *t)
projection_matrix_calc(t, t->con.pmtx);
}
-/*-------------- HELPER FUNCTIONS ----------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Helper Functions
+ * \{ */
int constraintModeToIndex(const TransInfo *t)
{
@@ -1147,14 +1158,13 @@ bool isLockConstraint(TransInfo *t)
return false;
}
-/*
+/**
* Returns the dimension of the constraint space.
*
* For that reason, the flags always needs to be set to properly evaluate here,
- * even if they aren't actually used in the callback function. (Which could happen
- * for weird constraints not yet designed. Along a path for example.)
+ * even if they aren't actually used in the callback function.
+ * (Which could happen for weird constraints not yet designed. Along a path for example.)
*/
-
int getConstraintSpaceDimension(TransInfo *t)
{
int n = 0;
@@ -1172,11 +1182,12 @@ int getConstraintSpaceDimension(TransInfo *t)
}
return n;
- /*
- * Someone willing to do it cryptically could do the following instead:
+ /* Someone willing to do it cryptically could do the following instead:
*
- * return t->con & (CON_AXIS0|CON_AXIS1|CON_AXIS2);
+ * `return t->con & (CON_AXIS0|CON_AXIS1|CON_AXIS2);`
*
* Based on the assumptions that the axis flags are one after the other and start at 1
*/
}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 3ea0b0a0a70..6b2e9dd9840 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -23,6 +23,7 @@
#include "DNA_anim_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_mesh_types.h"
#include "MEM_guardedalloc.h"
@@ -892,7 +893,6 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
special_aftertrans_update__node(C, t);
break;
case TC_OBJECT:
- case TC_OBJECT_TEXSPACE:
special_aftertrans_update__object(C, t);
break;
case TC_SCULPT:
@@ -912,6 +912,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
case TC_LATTICE_VERTS:
case TC_MBALL_VERTS:
case TC_MESH_UV:
+ case TC_MESH_SKIN:
+ case TC_OBJECT_TEXSPACE:
case TC_PAINT_CURVE_VERTS:
case TC_PARTICLE_VERTS:
case TC_NONE:
@@ -928,10 +930,10 @@ int special_transform_moving(TransInfo *t)
if (t->spacetype == SPACE_GRAPH) {
return G_TRANSFORM_FCURVES;
}
- if ((t->flag & T_EDIT) || (t->flag & T_POSE)) {
+ if ((t->flag & T_EDIT) || (t->options & CTX_POSE_BONE)) {
return G_TRANSFORM_EDIT;
}
- if (t->flag & (T_OBJECT | T_TEXTURE)) {
+ if (t->options & (CTX_OBJECT | CTX_TEXTURE_SPACE)) {
return G_TRANSFORM_OBJ;
}
@@ -973,53 +975,254 @@ static int countAndCleanTransDataContainer(TransInfo *t)
return t->data_len_all;
}
-void createTransData(bContext *C, TransInfo *t)
+static void init_proportional_edit(TransInfo *t)
{
- Scene *scene = t->scene;
- ViewLayer *view_layer = t->view_layer;
- Object *ob = OBACT(view_layer);
+ eTConvertType convert_type = t->data_type;
+ switch (convert_type) {
+ case TC_ACTION_DATA:
+ case TC_CURVE_VERTS:
+ case TC_GRAPH_EDIT_DATA:
+ case TC_GPENCIL:
+ case TC_LATTICE_VERTS:
+ case TC_MASKING_DATA:
+ case TC_MBALL_VERTS:
+ case TC_MESH_VERTS:
+ case TC_MESH_EDGES:
+ case TC_MESH_SKIN:
+ case TC_MESH_UV:
+ case TC_NODE_DATA:
+ case TC_OBJECT:
+ case TC_PARTICLE_VERTS:
+ break;
+ case TC_POSE: /* Disable PET, its not usable in pose mode yet T32444. */
+ case TC_ARMATURE_VERTS:
+ case TC_CURSOR_IMAGE:
+ case TC_CURSOR_VIEW3D:
+ case TC_NLA_DATA:
+ case TC_OBJECT_TEXSPACE:
+ case TC_PAINT_CURVE_VERTS:
+ case TC_SCULPT:
+ case TC_SEQ_DATA:
+ case TC_TRACKING_DATA:
+ case TC_NONE:
+ default:
+ t->options |= CTX_NO_PET;
+ t->flag &= ~T_PROP_EDIT_ALL;
+ return;
+ }
- t->data_len_all = -1;
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
+ if (convert_type == TC_OBJECT) {
+ /* Selected objects are already first, no need to presort. */
+ }
+ else {
+ sort_trans_data_selected_first(t);
+ }
- eTransConvertType convert_type = TC_NONE;
+ if (ELEM(convert_type, TC_ACTION_DATA, TC_GRAPH_EDIT_DATA)) {
+ /* Distance has already been set. */
+ }
+ else if (ELEM(convert_type, TC_MESH_VERTS, TC_MESH_SKIN)) {
+ if (t->flag & T_PROP_CONNECTED) {
+ /* Already calculated by transform_convert_mesh_connectivity_distance. */
+ }
+ else {
+ set_prop_dist(t, false);
+ }
+ }
+ else if (convert_type == TC_MESH_UV && t->flag & T_PROP_CONNECTED) {
+ /* Already calculated by uv_set_connectivity_distance. */
+ }
+ else if (convert_type == TC_CURVE_VERTS && t->obedit_type == OB_CURVE) {
+ set_prop_dist(t, false);
+ }
+ else {
+ set_prop_dist(t, true);
+ }
+
+ sort_trans_data_dist(t);
+ }
+ else if (ELEM(t->obedit_type, OB_CURVE)) {
+ /* Needed because bezier handles can be partially selected
+ * and are still added into transform data. */
+ sort_trans_data_selected_first(t);
+ }
+}
+
+/* For multi object editing. */
+static void init_TransDataContainers(TransInfo *t,
+ Object *obact,
+ Object **objects,
+ uint objects_len)
+{
+ switch (t->data_type) {
+ case TC_POSE:
+ case TC_ARMATURE_VERTS:
+ case TC_CURVE_VERTS:
+ case TC_GPENCIL:
+ case TC_LATTICE_VERTS:
+ case TC_MBALL_VERTS:
+ case TC_MESH_VERTS:
+ case TC_MESH_EDGES:
+ case TC_MESH_SKIN:
+ case TC_MESH_UV:
+ break;
+ case TC_ACTION_DATA:
+ case TC_GRAPH_EDIT_DATA:
+ case TC_CURSOR_IMAGE:
+ case TC_CURSOR_VIEW3D:
+ case TC_MASKING_DATA:
+ case TC_NLA_DATA:
+ case TC_NODE_DATA:
+ case TC_OBJECT:
+ case TC_OBJECT_TEXSPACE:
+ case TC_PAINT_CURVE_VERTS:
+ case TC_PARTICLE_VERTS:
+ case TC_SCULPT:
+ case TC_SEQ_DATA:
+ case TC_TRACKING_DATA:
+ case TC_NONE:
+ default:
+ /* Does not support Multi object editing. */
+ return;
+ }
+
+ const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
+ const short object_type = obact ? obact->type : -1;
+
+ if ((object_mode & OB_MODE_EDIT) || (t->data_type == TC_GPENCIL) ||
+ ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE))) {
+ if (t->data_container) {
+ MEM_freeN(t->data_container);
+ }
+
+ bool free_objects = false;
+ if (objects == NULL) {
+ objects = BKE_view_layer_array_from_objects_in_mode(
+ t->view_layer,
+ (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
+ &objects_len,
+ {
+ .object_mode = object_mode,
+ .no_dup_data = true,
+ });
+ free_objects = true;
+ }
+
+ t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__);
+ t->data_container_len = objects_len;
+
+ for (int i = 0; i < objects_len; i++) {
+ TransDataContainer *tc = &t->data_container[i];
+ if (((t->flag & T_NO_MIRROR) == 0) && ((t->options & CTX_NO_MIRROR) == 0) &&
+ (objects[i]->type == OB_MESH)) {
+ tc->use_mirror_axis_x = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_X) != 0;
+ tc->use_mirror_axis_y = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Y) != 0;
+ tc->use_mirror_axis_z = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Z) != 0;
+ }
+
+ if (object_mode & OB_MODE_EDIT) {
+ tc->obedit = objects[i];
+ /* Check needed for UV's */
+ if ((t->flag & T_2D_EDIT) == 0) {
+ tc->use_local_mat = true;
+ }
+ }
+ else if (object_mode & OB_MODE_POSE) {
+ tc->poseobj = objects[i];
+ tc->use_local_mat = true;
+ }
+ else if (t->data_type == TC_GPENCIL) {
+ tc->use_local_mat = true;
+ }
+
+ if (tc->use_local_mat) {
+ BLI_assert((t->flag & T_2D_EDIT) == 0);
+ copy_m4_m4(tc->mat, objects[i]->obmat);
+ copy_m3_m4(tc->mat3, tc->mat);
+ /* for non-invertible scale matrices, invert_m4_m4_fallback()
+ * can still provide a valid pivot */
+ invert_m4_m4_fallback(tc->imat, tc->mat);
+ invert_m3_m3(tc->imat3, tc->mat3);
+ normalize_m3_m3(tc->mat3_unit, tc->mat3);
+ }
+ /* Otherwise leave as zero. */
+ }
+
+ if (free_objects) {
+ MEM_freeN(objects);
+ }
+ }
+}
+
+static eTFlag flags_from_data_type(eTConvertType data_type)
+{
+ switch (data_type) {
+ case TC_ACTION_DATA:
+ case TC_GRAPH_EDIT_DATA:
+ case TC_MASKING_DATA:
+ case TC_NLA_DATA:
+ case TC_NODE_DATA:
+ case TC_PAINT_CURVE_VERTS:
+ case TC_SEQ_DATA:
+ case TC_TRACKING_DATA:
+ return T_POINTS | T_2D_EDIT;
+ case TC_ARMATURE_VERTS:
+ case TC_CURVE_VERTS:
+ case TC_GPENCIL:
+ case TC_LATTICE_VERTS:
+ case TC_MBALL_VERTS:
+ case TC_MESH_VERTS:
+ case TC_MESH_SKIN:
+ return T_EDIT | T_POINTS;
+ case TC_MESH_EDGES:
+ return T_EDIT;
+ case TC_MESH_UV:
+ return T_EDIT | T_POINTS | T_2D_EDIT;
+ case TC_PARTICLE_VERTS:
+ return T_POINTS;
+ case TC_POSE:
+ case TC_CURSOR_IMAGE:
+ case TC_CURSOR_VIEW3D:
+ case TC_OBJECT:
+ case TC_OBJECT_TEXSPACE:
+ case TC_SCULPT:
+ case TC_NONE:
+ default:
+ break;
+ }
+ return 0;
+}
+
+static eTConvertType convert_type_get(const TransInfo *t, Object **r_obj_armature)
+{
+ ViewLayer *view_layer = t->view_layer;
+ Object *ob = OBACT(view_layer);
+ eTConvertType convert_type = TC_NONE;
/* if tests must match recalcData for correct updates */
if (t->options & CTX_CURSOR) {
- t->flag |= T_CURSOR;
-
if (t->spacetype == SPACE_IMAGE) {
convert_type = TC_CURSOR_IMAGE;
}
else {
convert_type = TC_CURSOR_VIEW3D;
}
-
- /* Since we're transforming the cursor, initialize this value before it's modified.
- * Needed for #snap_grid_apply to access the cursor location. */
- transformCenter_from_type(t, V3D_AROUND_CURSOR);
}
else if (!(t->options & CTX_PAINT_CURVE) && (t->spacetype == SPACE_VIEW3D) && ob &&
(ob->mode == OB_MODE_SCULPT) && ob->sculpt) {
convert_type = TC_SCULPT;
}
- else if (t->options & CTX_TEXTURE) {
- t->flag |= T_TEXTURE;
+ else if (t->options & CTX_TEXTURE_SPACE) {
convert_type = TC_OBJECT_TEXSPACE;
}
- else if (t->options & CTX_EDGE) {
- t->flag |= T_EDIT;
+ else if (t->options & CTX_EDGE_DATA) {
convert_type = TC_MESH_EDGES;
- /* Multi object editing. */
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
}
else if (t->options & CTX_GPENCIL_STROKES) {
- t->options |= CTX_GPENCIL_STROKES;
- t->flag |= T_POINTS | T_EDIT;
convert_type = TC_GPENCIL;
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
}
else if (t->spacetype == SPACE_IMAGE) {
- t->flag |= T_POINTS | T_2D_EDIT;
if (t->options & CTX_MASK) {
convert_type = TC_MASKING_DATA;
}
@@ -1029,41 +1232,25 @@ void createTransData(bContext *C, TransInfo *t)
}
}
else if (t->obedit_type == OB_MESH) {
- t->flag |= T_EDIT;
convert_type = TC_MESH_UV;
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
}
}
else if (t->spacetype == SPACE_ACTION) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
convert_type = TC_ACTION_DATA;
}
else if (t->spacetype == SPACE_NLA) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
convert_type = TC_NLA_DATA;
}
else if (t->spacetype == SPACE_SEQ) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
- t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point trasnform */
convert_type = TC_SEQ_DATA;
}
else if (t->spacetype == SPACE_GRAPH) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
convert_type = TC_GRAPH_EDIT_DATA;
}
else if (t->spacetype == SPACE_NODE) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
convert_type = TC_NODE_DATA;
}
else if (t->spacetype == SPACE_CLIP) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
-
if (t->options & CTX_MOVIECLIP) {
convert_type = TC_TRACKING_DATA;
}
@@ -1072,11 +1259,6 @@ void createTransData(bContext *C, TransInfo *t)
}
}
else if (t->obedit_type != -1) {
- t->flag |= T_EDIT | T_POINTS;
-
- /* Multi object editing. */
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
-
if (t->obedit_type == OB_MESH) {
if (t->mode == TFM_SKIN_RESIZE) {
convert_type = TC_MESH_SKIN;
@@ -1095,46 +1277,25 @@ void createTransData(bContext *C, TransInfo *t)
convert_type = TC_MBALL_VERTS;
}
else if (t->obedit_type == OB_ARMATURE) {
- t->flag &= ~T_PROP_EDIT;
convert_type = TC_ARMATURE_VERTS;
}
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- /* XXX this is currently limited to active armature only... */
-
- /* XXX active-layer checking isn't done
- * as that should probably be checked through context instead. */
-
- /* Multi object editing. */
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
convert_type = TC_POSE;
}
else if (ob && (ob->mode & OB_MODE_ALL_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
- /* Important that ob_armature can be set even when its not selected T23412.
- * 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) {
- Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature);
- if (base_arm) {
- View3D *v3d = t->view;
- if (BASE_VISIBLE(v3d, base_arm)) {
- Object *objects[1];
- objects[0] = ob_armature;
- uint objects_len = 1;
- initTransDataContainers_FromObjectData(t, ob_armature, objects, objects_len);
- convert_type = TC_POSE;
- }
- }
+ Object *ob_armature = transform_object_deform_pose_armature_get(t, ob);
+ if (ob_armature) {
+ *r_obj_armature = ob_armature;
+ convert_type = TC_POSE;
}
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) &&
- PE_start_edit(PE_get_current(t->depsgraph, scene, ob))) {
- t->flag |= T_POINTS;
+ PE_start_edit(PE_get_current(t->depsgraph, t->scene, ob))) {
convert_type = TC_PARTICLE_VERTS;
}
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
- t->flag |= T_POINTS | T_2D_EDIT;
convert_type = TC_PAINT_CURVE_VERTS;
}
}
@@ -1146,47 +1307,55 @@ void createTransData(bContext *C, TransInfo *t)
/* In grease pencil all transformations must be canceled if not Object or Edit. */
}
else {
- /* Needed for correct Object.obmat after duplication, see: T62135. */
- BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context));
-
- if ((scene->toolsettings->transform_flag & SCE_XFORM_DATA_ORIGIN) != 0) {
- t->options |= CTX_OBMODE_XFORM_OBDATA;
- }
- if ((scene->toolsettings->transform_flag & SCE_XFORM_SKIP_CHILDREN) != 0) {
- t->options |= CTX_OBMODE_XFORM_SKIP_CHILDREN;
- }
-
- t->flag |= T_OBJECT;
convert_type = TC_OBJECT;
}
- t->data_type = convert_type;
- bool init_prop_edit = (t->flag & T_PROP_EDIT) != 0;
+ return convert_type;
+}
+
+void createTransData(bContext *C, TransInfo *t)
+{
+ t->data_len_all = -1;
+
+ Object *ob_armature = NULL;
+ t->data_type = convert_type_get(t, &ob_armature);
+ t->flag |= flags_from_data_type(t->data_type);
- switch (convert_type) {
+ if (ob_armature) {
+ init_TransDataContainers(t, ob_armature, &ob_armature, 1);
+ }
+ else {
+ ViewLayer *view_layer = t->view_layer;
+ Object *ob = OBACT(view_layer);
+ init_TransDataContainers(t, ob, NULL, 0);
+ }
+
+ switch (t->data_type) {
case TC_ACTION_DATA:
+ t->obedit_type = -1;
createTransActionData(C, t);
break;
case TC_POSE:
+ t->options |= CTX_POSE_BONE;
+
+ /* XXX active-layer checking isn't done
+ * as that should probably be checked through context instead. */
createTransPose(t);
- /* Disable PET, its not usable in pose mode yet T32444. */
- init_prop_edit = false;
break;
case TC_ARMATURE_VERTS:
createTransArmatureVerts(t);
break;
case TC_CURSOR_IMAGE:
createTransCursor_image(t);
- init_prop_edit = false;
break;
case TC_CURSOR_VIEW3D:
createTransCursor_view3d(t);
- init_prop_edit = false;
break;
case TC_CURVE_VERTS:
createTransCurveVerts(t);
break;
case TC_GRAPH_EDIT_DATA:
+ t->obedit_type = -1;
createTransGraphEditData(C, t);
break;
case TC_GPENCIL:
@@ -1196,6 +1365,9 @@ void createTransData(bContext *C, TransInfo *t)
createTransLatticeVerts(t);
break;
case TC_MASKING_DATA:
+ if (t->spacetype == SPACE_CLIP) {
+ t->obedit_type = -1;
+ }
createTransMaskingData(C, t);
break;
case TC_MBALL_VERTS:
@@ -1214,13 +1386,25 @@ void createTransData(bContext *C, TransInfo *t)
createTransUVs(C, t);
break;
case TC_NLA_DATA:
+ t->obedit_type = -1;
createTransNlaData(C, t);
- init_prop_edit = false;
break;
case TC_NODE_DATA:
+ t->obedit_type = -1;
createTransNodeData(t);
break;
case TC_OBJECT:
+ t->options |= CTX_OBJECT;
+
+ /* Needed for correct Object.obmat after duplication, see: T62135. */
+ BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context));
+
+ if ((t->settings->transform_flag & SCE_XFORM_DATA_ORIGIN) != 0) {
+ t->options |= CTX_OBMODE_XFORM_OBDATA;
+ }
+ if ((t->settings->transform_flag & SCE_XFORM_SKIP_CHILDREN) != 0) {
+ t->options |= CTX_OBMODE_XFORM_SKIP_CHILDREN;
+ }
createTransObject(C, t);
/* Check if we're transforming the camera from the camera */
if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
@@ -1229,36 +1413,34 @@ void createTransData(bContext *C, TransInfo *t)
if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) {
/* we could have a flag to easily check an object is being transformed */
if (v3d->camera->id.tag & LIB_TAG_DOIT) {
- t->flag |= T_CAMERA;
+ t->options |= CTX_CAMERA;
}
}
else if (v3d->ob_center && v3d->ob_center->id.tag & LIB_TAG_DOIT) {
- t->flag |= T_CAMERA;
+ t->options |= CTX_CAMERA;
}
}
break;
case TC_OBJECT_TEXSPACE:
createTransTexspace(t);
- init_prop_edit = false;
break;
case TC_PAINT_CURVE_VERTS:
createTransPaintCurveVerts(C, t);
- init_prop_edit = false;
break;
case TC_PARTICLE_VERTS:
createTransParticleVerts(t);
break;
case TC_SCULPT:
createTransSculpt(C, t);
- init_prop_edit = false;
break;
case TC_SEQ_DATA:
+ t->obedit_type = -1;
+ t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point transform. */
createTransSeqData(t);
- init_prop_edit = false;
break;
case TC_TRACKING_DATA:
+ t->obedit_type = -1;
createTransTrackingData(C, t);
- init_prop_edit = false;
break;
case TC_NONE:
default:
@@ -1270,48 +1452,7 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
- if (t->data_len_all && init_prop_edit) {
- if (convert_type == TC_OBJECT) {
- /* Selected objects are already first, no need to presort. */
- }
- else {
- sort_trans_data_selected_first(t);
- }
-
- if (ELEM(convert_type, TC_ACTION_DATA, TC_GRAPH_EDIT_DATA)) {
- /* Distance has already been set. */
- }
- else if (ELEM(convert_type, TC_MESH_VERTS, TC_MESH_SKIN)) {
- if (t->flag & T_PROP_CONNECTED) {
- /* Already calculated by transform_convert_mesh_connectivity_distance. */
- }
- else {
- set_prop_dist(t, false);
- }
- }
- else if (convert_type == TC_MESH_UV && t->flag & T_PROP_CONNECTED) {
- /* Already calculated by uv_set_connectivity_distance. */
- }
- else if (convert_type == TC_CURVE_VERTS && t->obedit_type == OB_CURVE) {
- set_prop_dist(t, false);
- }
- else {
- set_prop_dist(t, true);
- }
-
- sort_trans_data_dist(t);
- }
- else {
- if (ELEM(t->obedit_type, OB_CURVE)) {
- /* Needed because bezier handles can be partially selected
- * and are still added into transform data. */
- sort_trans_data_selected_first(t);
- }
-
- if (!init_prop_edit) {
- t->flag &= ~T_PROP_EDIT_ALL;
- }
- }
+ init_proportional_edit(t);
BLI_assert((!(t->flag & T_EDIT)) == (!(t->obedit_type != -1)));
}
@@ -1557,9 +1698,11 @@ void recalcData(TransInfo *t)
flushTransNodes(t);
break;
case TC_OBJECT:
- case TC_OBJECT_TEXSPACE:
recalcData_objects(t);
break;
+ case TC_OBJECT_TEXSPACE:
+ recalcData_texspace(t);
+ break;
case TC_PAINT_CURVE_VERTS:
flushTransPaintCurve(t);
break;
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index 466bfd6b226..bd7569b3771 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -49,37 +49,9 @@ void mesh_customdatacorrect_init(TransInfo *t);
/* transform_convert_sequencer.c */
int transform_convert_sequencer_get_snap_bound(TransInfo *t);
-
+void transform_convert_sequencer_channel_clamp(TransInfo *t);
/********************* intern **********************/
-typedef enum eTransConvertType {
- TC_NONE = 0,
- TC_ACTION_DATA,
- TC_POSE,
- TC_ARMATURE_VERTS,
- TC_CURSOR_IMAGE,
- TC_CURSOR_VIEW3D,
- TC_CURVE_VERTS,
- TC_GRAPH_EDIT_DATA,
- TC_GPENCIL,
- TC_LATTICE_VERTS,
- TC_MASKING_DATA,
- TC_MBALL_VERTS,
- TC_MESH_VERTS,
- TC_MESH_EDGES,
- TC_MESH_SKIN,
- TC_MESH_UV,
- TC_NLA_DATA,
- TC_NODE_DATA,
- TC_OBJECT,
- TC_OBJECT_TEXSPACE,
- TC_PAINT_CURVE_VERTS,
- TC_PARTICLE_VERTS,
- TC_SCULPT,
- TC_SEQ_DATA,
- TC_TRACKING_DATA,
-} eTransConvertType;
-
/* transform_convert.c */
bool transform_mode_use_local_origins(const TransInfo *t);
void transform_around_single_fallback_ex(TransInfo *t, int data_len_all);
@@ -215,10 +187,13 @@ void special_aftertrans_update__node(bContext *C, TransInfo *t);
/* transform_convert_object.c */
void createTransObject(bContext *C, TransInfo *t);
-void createTransTexspace(TransInfo *t);
void recalcData_objects(TransInfo *t);
void special_aftertrans_update__object(bContext *C, TransInfo *t);
+/* transform_convert_object_texspace.c */
+void createTransTexspace(TransInfo *t);
+void recalcData_texspace(TransInfo *t);
+
/* transform_convert_paintcurve.c */
void createTransPaintCurveVerts(bContext *C, TransInfo *t);
void flushTransPaintCurve(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index e9b2273b343..71b9e11b51f 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -444,7 +444,7 @@ static short pose_grab_with_ik(Main *bmain, Object *ob)
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->layer & arm->layer) {
if (pchan->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) {
- /* Rule: no IK for solitatry (unconnected) bones */
+ /* Rule: no IK for solitary (unconnected) bones. */
for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) {
if (bonec->flag & BONE_CONNECTED) {
break;
@@ -870,8 +870,6 @@ void createTransPose(TransInfo *t)
t->mode = TFM_RESIZE;
}
}
-
- t->flag |= T_POSE;
}
void createTransArmatureVerts(TransInfo *t)
@@ -1354,7 +1352,7 @@ static void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, O
}
mul_v3_m4v3(data->grabtarget, flip_mtx, td->loc);
if (pid) {
- /* TODO(germano): Realitve Mirror support */
+ /* TODO(germano): Relative Mirror support. */
}
data->flag |= CONSTRAINT_IK_AUTO;
/* Add a temporary auto IK constraint here, as we will only temporarily active this
diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c
index 445253d5446..3c01c716123 100644
--- a/source/blender/editors/transform/transform_convert_curve.c
+++ b/source/blender/editors/transform/transform_convert_curve.c
@@ -298,7 +298,7 @@ void createTransCurveVerts(TransInfo *t)
}
if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0) {
- /* If the middle is selected but the sides arnt, this is needed */
+ /* If the middle is selected but the sides aren't, this is needed. */
if (hdata == NULL) {
/* if the handle was not saved by the previous handle */
hdata = initTransDataCurveHandles(td, bezt);
diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index deb18b50a22..eaa8962326a 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -135,7 +135,7 @@ static void createTransGPencil_curves(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* Check if stroke has an editcurve */
@@ -242,7 +242,7 @@ static void createTransGPencil_curves(bContext *C,
}
/* Calculate difference matrix. */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
copy_m3_m4(mtx, diff_mat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
@@ -263,7 +263,7 @@ static void createTransGPencil_curves(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* Check if stroke has an editcurve */
@@ -436,7 +436,7 @@ static void createTransGPencil_strokes(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
@@ -507,7 +507,7 @@ static void createTransGPencil_strokes(bContext *C,
}
/* Calculate difference matrix. */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
/* Undo matrix. */
invert_m4_m4(inverse_diff_mat, diff_mat);
@@ -551,7 +551,7 @@ static void createTransGPencil_strokes(bContext *C,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* What we need to include depends on proportional editing settings... */
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index b3bd6b31879..ce74c5f5a36 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -251,29 +251,55 @@ void transform_convert_mesh_islanddata_free(struct TransIslandData *island_data)
*
* \{ */
-static bool bmesh_test_dist_add(BMVert *v,
- BMVert *v_other,
+/* Propagate distance from v1 and v2 to v0. */
+static bool bmesh_test_dist_add(BMVert *v0,
+ BMVert *v1,
+ BMVert *v2,
float *dists,
- const float *dists_prev,
/* optionally track original index */
int *index,
- const int *index_prev,
const float mtx[3][3])
{
- if ((BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) &&
- (BM_elem_flag_test(v_other, BM_ELEM_HIDDEN) == 0)) {
- const int i = BM_elem_index_get(v);
- const int i_other = BM_elem_index_get(v_other);
- float vec[3];
- float dist_other;
- sub_v3_v3v3(vec, v->co, v_other->co);
- mul_m3_v3(mtx, vec);
-
- dist_other = dists_prev[i] + len_v3(vec);
- if (dist_other < dists[i_other]) {
- dists[i_other] = dist_other;
+ if ((BM_elem_flag_test(v0, BM_ELEM_SELECT) == 0) &&
+ (BM_elem_flag_test(v0, BM_ELEM_HIDDEN) == 0)) {
+ const int i0 = BM_elem_index_get(v0);
+ const int i1 = BM_elem_index_get(v1);
+
+ BLI_assert(dists[i1] != FLT_MAX);
+ if (dists[i0] <= dists[i1]) {
+ return false;
+ }
+
+ float dist0;
+
+ if (v2) {
+ /* Distance across triangle. */
+ const int i2 = BM_elem_index_get(v2);
+ BLI_assert(dists[i2] != FLT_MAX);
+ if (dists[i0] <= dists[i2]) {
+ return false;
+ }
+
+ float vm0[3], vm1[3], vm2[3];
+ mul_v3_m3v3(vm0, mtx, v0->co);
+ mul_v3_m3v3(vm1, mtx, v1->co);
+ mul_v3_m3v3(vm2, mtx, v2->co);
+
+ dist0 = geodesic_distance_propagate_across_triangle(vm0, vm1, vm2, dists[i1], dists[i2]);
+ }
+ else {
+ /* Distance along edge. */
+ float vec[3];
+ sub_v3_v3v3(vec, v1->co, v0->co);
+ mul_m3_v3(mtx, vec);
+
+ dist0 = dists[i1] + len_v3(vec);
+ }
+
+ if (dist0 < dists[i0]) {
+ dists[i0] = dist0;
if (index != NULL) {
- index[i_other] = index_prev[i];
+ index[i0] = index[i1];
}
return true;
}
@@ -292,15 +318,16 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
float *dists,
int *index)
{
- BLI_LINKSTACK_DECLARE(queue, BMVert *);
+ BLI_LINKSTACK_DECLARE(queue, BMEdge *);
- /* any BM_ELEM_TAG'd vertex is in 'queue_next', so we don't add in twice */
- BLI_LINKSTACK_DECLARE(queue_next, BMVert *);
+ /* any BM_ELEM_TAG'd edge is in 'queue_next', so we don't add in twice */
+ BLI_LINKSTACK_DECLARE(queue_next, BMEdge *);
BLI_LINKSTACK_INIT(queue);
BLI_LINKSTACK_INIT(queue_next);
{
+ /* Set indexes and initial distances for selected vertices. */
BMIter viter;
BMVert *v;
int i;
@@ -308,7 +335,6 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
float dist;
BM_elem_index_set(v, i); /* set_inline */
- BM_elem_flag_disable(v, BM_ELEM_TAG);
if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
dist = FLT_MAX;
@@ -317,7 +343,6 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
}
}
else {
- BLI_LINKSTACK_PUSH(queue, v);
dist = 0.0f;
if (index != NULL) {
index[i] = i;
@@ -329,103 +354,99 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
bm->elem_index_dirty &= ~BM_VERT;
}
- /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
- float *dists_prev = MEM_dupallocN(dists);
- int *index_prev = MEM_dupallocN(index); /* may be NULL */
+ {
+ /* Add edges with at least one selected vertex to the queue. */
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ BMVert *v1 = e->v1;
+ BMVert *v2 = e->v2;
+ int i1 = BM_elem_index_get(v1);
+ int i2 = BM_elem_index_get(v2);
+
+ if (dists[i1] != FLT_MAX || dists[i2] != FLT_MAX) {
+ BLI_LINKSTACK_PUSH(queue, e);
+ }
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ }
do {
- BMVert *v;
- LinkNode *lnk;
-
- /* this is correct but slow to do each iteration,
- * instead sync the dist's while clearing BM_ELEM_TAG (below) */
-#if 0
- memcpy(dists_prev, dists, sizeof(float) * bm->totvert);
-#endif
-
- while ((v = BLI_LINKSTACK_POP(queue))) {
- BLI_assert(dists[BM_elem_index_get(v)] != FLT_MAX);
-
- /* connected edge-verts */
- if (v->e != NULL) {
- BMEdge *e_iter, *e_first;
-
- e_iter = e_first = v->e;
-
- /* would normally use BM_EDGES_OF_VERT, but this runs so often,
- * its faster to iterate on the data directly */
- do {
-
- if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == 0) {
+ BMEdge *e;
+
+ while ((e = BLI_LINKSTACK_POP(queue))) {
+ BMVert *v1 = e->v1;
+ BMVert *v2 = e->v2;
+ int i1 = BM_elem_index_get(v1);
+ int i2 = BM_elem_index_get(v2);
+
+ if (e->l == NULL || (dists[i1] == FLT_MAX || dists[i2] == FLT_MAX)) {
+ /* Propagate along edge from vertex with smallest to largest distance. */
+ if (dists[i1] > dists[i2]) {
+ SWAP(int, i1, i2);
+ SWAP(BMVert *, v1, v2);
+ }
- /* edge distance */
- {
- BMVert *v_other = BM_edge_other_vert(e_iter, v);
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
- if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
- BM_elem_flag_enable(v_other, BM_ELEM_TAG);
- BLI_LINKSTACK_PUSH(queue_next, v_other);
- }
- }
+ if (bmesh_test_dist_add(v2, v1, NULL, dists, index, mtx)) {
+ /* Add adjacent loose edges to the queue, or all edges if this is a loose edge.
+ * Other edges are handled by propagation across edges below. */
+ BMEdge *e_other;
+ BMIter eiter;
+ BM_ITER_ELEM (e_other, &eiter, v2, BM_EDGES_OF_VERT) {
+ if (e_other != e && BM_elem_flag_test(e_other, BM_ELEM_TAG) == 0 &&
+ (e->l == NULL || e_other->l == NULL)) {
+ BM_elem_flag_enable(e_other, BM_ELEM_TAG);
+ BLI_LINKSTACK_PUSH(queue_next, e_other);
}
+ }
+ }
+ }
- /* face distance */
- if (e_iter->l) {
- BMLoop *l_iter_radial, *l_first_radial;
- /**
- * imaginary edge diagonally across quad.
- * \note This takes advantage of the rules of winding that we
- * know 2 or more of a verts edges wont reference the same face twice.
- * Also, if the edge is hidden, the face will be hidden too.
- */
- l_iter_radial = l_first_radial = e_iter->l;
-
- do {
- if ((l_iter_radial->v == v) && (l_iter_radial->f->len == 4) &&
- (BM_elem_flag_test(l_iter_radial->f, BM_ELEM_HIDDEN) == 0)) {
- BMVert *v_other = l_iter_radial->next->next->v;
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
- if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
- BM_elem_flag_enable(v_other, BM_ELEM_TAG);
- BLI_LINKSTACK_PUSH(queue_next, v_other);
- }
- }
+ if (e->l != NULL) {
+ /* Propagate across edge to vertices in adjacent faces. */
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
+ for (BMLoop *l_other = l->next->next; l_other != l; l_other = l_other->next) {
+ BMVert *v_other = l_other->v;
+ BLI_assert(!ELEM(v_other, v1, v2));
+
+ if (bmesh_test_dist_add(v_other, v1, v2, dists, index, mtx)) {
+ /* Add adjacent edges to the queue, if they are ready to propagate across/along.
+ * Always propagate along loose edges, and for other edges only propagate across
+ * if both vertices have a known distances. */
+ BMEdge *e_other;
+ BMIter eiter;
+ BM_ITER_ELEM (e_other, &eiter, v_other, BM_EDGES_OF_VERT) {
+ if (e_other != e && BM_elem_flag_test(e_other, BM_ELEM_TAG) == 0 &&
+ (e_other->l == NULL ||
+ dists[BM_elem_index_get(BM_edge_other_vert(e_other, v_other))] != FLT_MAX)) {
+ BM_elem_flag_enable(e_other, BM_ELEM_TAG);
+ BLI_LINKSTACK_PUSH(queue_next, e_other);
}
- } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial);
+ }
}
}
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
+ }
}
}
- /* clear for the next loop */
- for (lnk = queue_next; lnk; lnk = lnk->next) {
- BMVert *v_link = lnk->link;
- const int i = BM_elem_index_get(v_link);
+ /* Clear for the next loop. */
+ for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) {
+ BMEdge *e_link = lnk->link;
- BM_elem_flag_disable(v_link, BM_ELEM_TAG);
-
- /* keep in sync, avoid having to do full memcpy each iteration */
- dists_prev[i] = dists[i];
- if (index != NULL) {
- index_prev[i] = index[i];
- }
+ BM_elem_flag_disable(e_link, BM_ELEM_TAG);
}
BLI_LINKSTACK_SWAP(queue, queue_next);
- /* none should be tagged now since 'queue_next' is empty */
- BLI_assert(BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
-
+ /* None should be tagged now since 'queue_next' is empty. */
+ BLI_assert(BM_iter_mesh_count_flag(BM_EDGES_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
} while (BLI_LINKSTACK_SIZE(queue));
BLI_LINKSTACK_FREE(queue);
BLI_LINKSTACK_FREE(queue_next);
-
- MEM_freeN(dists_prev);
- if (index_prev != NULL) {
- MEM_freeN(index_prev);
- }
}
/** \} */
@@ -1445,7 +1466,7 @@ static void mesh_customdatacorrect_apply_vert(struct TransCustomDataLayer *tcld,
*
* Interpolate from every other loop (not ideal)
* However values will only be taken from loops which overlap other mdisps.
- * */
+ */
const bool update_loop_mdisps = is_moved && do_loop_mdisps && (tcld->cd_loop_mdisp_offset != -1);
if (update_loop_mdisps) {
float(*faces_center)[3] = BLI_array_alloca(faces_center, l_num);
diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c
index 1807e9adcd1..b1024f5efe4 100644
--- a/source/blender/editors/transform/transform_convert_mesh_skin.c
+++ b/source/blender/editors/transform/transform_convert_mesh_skin.c
@@ -55,9 +55,7 @@ static float *mesh_skin_transdata_center(const struct TransIslandData *island_da
if (island_data->center && island_index != -1) {
return island_data->center[island_index];
}
- else {
- return eve->co;
- }
+ return eve->co;
}
static void mesh_skin_transdata_create(TransDataBasic *td,
diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c
index adc2d03e2dc..5eb3f68787a 100644
--- a/source/blender/editors/transform/transform_convert_nla.c
+++ b/source/blender/editors/transform/transform_convert_nla.c
@@ -304,7 +304,7 @@ void recalcData_nla(TransInfo *t)
for (i = 0; i < tc->data_len; i++, tdn++) {
NlaStrip *strip = tdn->strip;
PointerRNA strip_ptr;
- short pExceeded, nExceeded, iter;
+ short iter;
int delta_y1, delta_y2;
/* if this tdn has no handles, that means it is just a dummy that should be skipped */
@@ -358,21 +358,31 @@ 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;
+ }
+
for (iter = 0; iter < 5; iter++) {
- pExceeded = ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) &&
- (tdn->h1[0] < strip->prev->end));
- nExceeded = ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) &&
- (tdn->h2[0] > strip->next->start));
+
+ const bool pExceeded = (prev != NULL) && (tdn->h1[0] < prev->end);
+ const bool nExceeded = (next != NULL) && (tdn->h2[0] > next->start);
if ((pExceeded && nExceeded) || (iter == 4)) {
- /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise)
+ /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a
+ * compromise)
* - Simply crop strip to fit within the bounds of the strips bounding it
* - If there were no neighbors, clear the transforms
* (make it default to the strip's current values).
*/
- if (strip->prev && strip->next) {
- tdn->h1[0] = strip->prev->end;
- tdn->h2[0] = strip->next->start;
+ if (prev && next) {
+ tdn->h1[0] = prev->end;
+ tdn->h2[0] = next->start;
}
else {
tdn->h1[0] = strip->start;
@@ -381,14 +391,14 @@ void recalcData_nla(TransInfo *t)
}
else if (nExceeded) {
/* move backwards */
- float offset = tdn->h2[0] - strip->next->start;
+ float offset = tdn->h2[0] - next->start;
tdn->h1[0] -= offset;
tdn->h2[0] -= offset;
}
else if (pExceeded) {
/* more forwards */
- float offset = strip->prev->end - tdn->h1[0];
+ float offset = prev->end - tdn->h1[0];
tdn->h1[0] += offset;
tdn->h2[0] += offset;
@@ -564,7 +574,7 @@ void special_aftertrans_update__nla(bContext *C, TransInfo *UNUSED(t))
/* free temp memory */
ANIM_animdata_freelist(&anim_data);
- /* perform after-transfrom validation */
+ /* Perform after-transform validation. */
ED_nla_postop_refresh(&ac);
}
}
diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c
index 90ffccfdd7b..5f6f00716f9 100644
--- a/source/blender/editors/transform/transform_convert_object.c
+++ b/source/blender/editors/transform/transform_convert_object.c
@@ -21,12 +21,8 @@
* \ingroup edtransform
*/
-#include "DNA_mesh_types.h"
-
#include "MEM_guardedalloc.h"
-#include "BLI_compiler_compat.h"
-#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -46,11 +42,11 @@
#include "DEG_depsgraph_query.h"
#include "transform.h"
+#include "transform_orientations.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
-#include "transform_orientations.h"
/* -------------------------------------------------------------------- */
/** \name Object Mode Custom Data
@@ -713,66 +709,6 @@ void createTransObject(bContext *C, TransInfo *t)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Texture Space Transform Creation
- *
- * Instead of transforming the selection, move the 2D/3D cursor.
- *
- * \{ */
-
-void createTransTexspace(TransInfo *t)
-{
- ViewLayer *view_layer = t->view_layer;
- TransData *td;
- Object *ob;
- ID *id;
- short *texflag;
-
- ob = OBACT(view_layer);
-
- if (ob == NULL) { /* Shouldn't logically happen, but still. */
- return;
- }
-
- id = ob->data;
- if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) {
- BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform");
- return;
- }
-
- if (BKE_object_obdata_is_libdata(ob)) {
- BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
- return;
- }
-
- {
- BLI_assert(t->data_container_len == 1);
- TransDataContainer *tc = t->data_container;
- tc->data_len = 1;
- td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
- td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
- }
-
- td->flag = TD_SELECTED;
- copy_v3_v3(td->center, ob->obmat[3]);
- td->ob = ob;
-
- copy_m3_m4(td->mtx, ob->obmat);
- copy_m3_m4(td->axismtx, ob->obmat);
- normalize_m3(td->axismtx);
- pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
-
- if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size)) {
- ob->dtx |= OB_TEXSPACE;
- *texflag &= ~ME_AUTOSPACE;
- }
-
- copy_v3_v3(td->iloc, td->loc);
- copy_v3_v3(td->ext->isize, td->ext->size);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Transform (Auto-Keyframing)
* \{ */
@@ -962,10 +898,6 @@ void recalcData_objects(TransInfo *t)
* otherwise proxies don't function correctly
*/
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
-
- if (t->flag & T_TEXTURE) {
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- }
}
}
@@ -991,7 +923,7 @@ void recalcData_objects(TransInfo *t)
void special_aftertrans_update__object(bContext *C, TransInfo *t)
{
- BLI_assert(t->flag & (T_OBJECT | T_TEXTURE));
+ BLI_assert(t->options & CTX_OBJECT);
Object *ob;
const bool canceled = (t->state == TRANS_CANCEL);
diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c
new file mode 100644
index 00000000000..195eb941b3b
--- /dev/null
+++ b/source/blender/editors/transform/transform_convert_object_texspace.c
@@ -0,0 +1,126 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edtransform
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "BKE_animsys.h"
+#include "BKE_context.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+
+#include "DNA_mesh_types.h"
+
+#include "transform.h"
+#include "transform_snap.h"
+
+/* Own include. */
+#include "transform_convert.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Texture Space Transform Creation
+ *
+ * Instead of transforming the selection, move the 2D/3D cursor.
+ *
+ * \{ */
+
+void createTransTexspace(TransInfo *t)
+{
+ ViewLayer *view_layer = t->view_layer;
+ TransData *td;
+ Object *ob;
+ ID *id;
+ short *texflag;
+
+ ob = OBACT(view_layer);
+
+ if (ob == NULL) { /* Shouldn't logically happen, but still. */
+ return;
+ }
+
+ id = ob->data;
+ if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) {
+ BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform");
+ return;
+ }
+
+ if (BKE_object_obdata_is_libdata(ob)) {
+ BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
+ return;
+ }
+
+ {
+ BLI_assert(t->data_container_len == 1);
+ TransDataContainer *tc = t->data_container;
+ tc->data_len = 1;
+ td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
+ td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
+ }
+
+ td->flag = TD_SELECTED;
+ copy_v3_v3(td->center, ob->obmat[3]);
+ td->ob = ob;
+
+ copy_m3_m4(td->mtx, ob->obmat);
+ copy_m3_m4(td->axismtx, ob->obmat);
+ normalize_m3(td->axismtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
+
+ if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size)) {
+ ob->dtx |= OB_TEXSPACE;
+ *texflag &= ~ME_AUTOSPACE;
+ }
+
+ copy_v3_v3(td->iloc, td->loc);
+ copy_v3_v3(td->ext->isize, td->ext->size);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Recalc Data object
+ *
+ * \{ */
+
+/* helper for recalcData() - for object transforms, typically in the 3D view */
+void recalcData_texspace(TransInfo *t)
+{
+
+ if (t->state != TRANS_CANCEL) {
+ applyProject(t);
+ }
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+
+ for (int i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+ DEG_id_tag_update(&td->ob->id, ID_RECALC_GEOMETRY);
+ }
+ }
+}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index ebb0b6823a3..22b1f9fd8d7 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -25,6 +25,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BKE_context.h"
@@ -64,6 +65,8 @@ typedef struct TransSeq {
int min;
int max;
bool snap_left;
+ int selection_channel_range_min;
+ int selection_channel_range_max;
} TransSeq;
/* -------------------------------------------------------------------- */
@@ -623,6 +626,14 @@ void createTransSeqData(TransInfo *t)
}
}
+ ts->selection_channel_range_min = MAXSEQ + 1;
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
+ if ((seq->flag & SELECT) != 0) {
+ ts->selection_channel_range_min = min_ii(ts->selection_channel_range_min, seq->machine);
+ ts->selection_channel_range_max = max_ii(ts->selection_channel_range_max, seq->machine);
+ }
+ }
+
#undef XXX_DURIAN_ANIM_TX_HACK
}
@@ -834,7 +845,7 @@ void special_aftertrans_update__sequencer(bContext *UNUSED(C), TransInfo *t)
/* Marker transform, not especially nice but we may want to move markers
* at the same time as strips in the Video Sequencer. */
if (sseq->flag & SEQ_MARKER_TRANS) {
- /* cant use TFM_TIME_EXTEND
+ /* can't use TFM_TIME_EXTEND
* for some reason EXTEND is changed into TRANSLATE, so use frame_side instead */
if (t->mode == TFM_SEQ_SLIDE) {
@@ -850,6 +861,21 @@ void special_aftertrans_update__sequencer(bContext *UNUSED(C), TransInfo *t)
}
}
+void transform_convert_sequencer_channel_clamp(TransInfo *t)
+{
+ const TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
+ const int channel_offset = round_fl_to_int(t->values[1]);
+ const int min_channel_after_transform = ts->selection_channel_range_min + channel_offset;
+ const int max_channel_after_transform = ts->selection_channel_range_max + channel_offset;
+
+ if (max_channel_after_transform > MAXSEQ) {
+ t->values[1] -= max_channel_after_transform - MAXSEQ;
+ }
+ if (min_channel_after_transform < 1) {
+ t->values[1] -= min_channel_after_transform - 1;
+ }
+}
+
int transform_convert_sequencer_get_snap_bound(TransInfo *t)
{
TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
diff --git a/source/blender/editors/transform/transform_convert_tracking.c b/source/blender/editors/transform/transform_convert_tracking.c
index c3f48adca68..5f5f06e388f 100644
--- a/source/blender/editors/transform/transform_convert_tracking.c
+++ b/source/blender/editors/transform/transform_convert_tracking.c
@@ -52,6 +52,7 @@ typedef struct TransDataTracking {
float (*smarkers)[2];
int markersnr;
+ int framenr;
MovieTrackingMarker *markers;
/* marker transformation from curves editor */
@@ -73,9 +74,25 @@ enum transDataTracking_Mode {
*
* \{ */
-static void markerToTransDataInit(TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+typedef struct TransformInitContext {
+ SpaceClip *space_clip;
+
+ TransInfo *t;
+ TransDataContainer *tc;
+
+ /* NOTE: These pointers will be `nullptr` during counting step.
+ * This means, that the transformation data initialization functions are to increment
+ * `tc->data_len` instead of filling in the transformation data when these pointers are
+ * `nullptr`. For simplicity, check the `current.td` against `nullptr`.
+ * Do not `tc->data_len` when filling in the transformation data. */
+ struct {
+ TransData *td;
+ TransData2D *td2d;
+ TransDataTracking *tdt;
+ } current;
+} TransformInitContext;
+
+static void markerToTransDataInit(TransformInitContext *init_context,
MovieTrackingTrack *track,
MovieTrackingMarker *marker,
int area,
@@ -84,8 +101,19 @@ static void markerToTransDataInit(TransData *td,
const float off[2],
const float aspect[2])
{
+ TransData *td = init_context->current.td;
+ TransData2D *td2d = init_context->current.td2d;
+ TransDataTracking *tdt = init_context->current.tdt;
+
+ if (td == NULL) {
+ init_context->tc->data_len++;
+ return;
+ }
+
int anchor = area == TRACK_AREA_POINT && off;
+ tdt->flag = marker->flag;
+ tdt->framenr = marker->framenr;
tdt->mode = transDataTracking_ModeTracks;
if (anchor) {
@@ -143,23 +171,20 @@ static void markerToTransDataInit(TransData *td,
unit_m3(td->mtx);
unit_m3(td->smtx);
+
+ init_context->current.td++;
+ init_context->current.td2d++;
+ init_context->current.tdt++;
}
-static void trackToTransData(const int framenr,
- TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void trackToTransData(TransformInitContext *init_context,
+ const int framenr,
MovieTrackingTrack *track,
const float aspect[2])
{
MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr);
- tdt->flag = marker->flag;
- marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
-
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_POINT,
@@ -170,16 +195,14 @@ static void trackToTransData(const int framenr,
if (track->flag & SELECT) {
markerToTransDataInit(
- td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, marker->pos, NULL, NULL, aspect);
+ init_context, track, marker, TRACK_AREA_POINT, marker->pos, NULL, NULL, aspect);
}
if (track->pat_flag & SELECT) {
int a;
for (a = 0; a < 4; a++) {
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_PAT,
@@ -191,9 +214,7 @@ static void trackToTransData(const int framenr,
}
if (track->search_flag & SELECT) {
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_SEARCH,
@@ -202,9 +223,7 @@ static void trackToTransData(const int framenr,
NULL,
aspect);
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_SEARCH,
@@ -213,15 +232,43 @@ static void trackToTransData(const int framenr,
NULL,
aspect);
}
+
+ if (init_context->current.td != NULL) {
+ marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
+ }
}
-static void planeMarkerToTransDataInit(TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void trackToTransDataIfNeeded(TransformInitContext *init_context,
+ const int framenr,
+ MovieTrackingTrack *track,
+ const float aspect[2])
+{
+ if (!TRACK_VIEW_SELECTED(init_context->space_clip, track)) {
+ return;
+ }
+ if (track->flag & TRACK_LOCKED) {
+ return;
+ }
+ trackToTransData(init_context, framenr, track, aspect);
+}
+
+static void planeMarkerToTransDataInit(TransformInitContext *init_context,
MovieTrackingPlaneTrack *plane_track,
+ MovieTrackingPlaneMarker *plane_marker,
float corner[2],
const float aspect[2])
{
+ TransData *td = init_context->current.td;
+ TransData2D *td2d = init_context->current.td2d;
+ TransDataTracking *tdt = init_context->current.tdt;
+
+ if (td == NULL) {
+ init_context->tc->data_len++;
+ return;
+ }
+
+ tdt->flag = plane_marker->flag;
+ tdt->framenr = plane_marker->framenr;
tdt->mode = transDataTracking_ModePlaneTracks;
tdt->plane_track = plane_track;
@@ -247,24 +294,38 @@ static void planeMarkerToTransDataInit(TransData *td,
unit_m3(td->mtx);
unit_m3(td->smtx);
+
+ init_context->current.td++;
+ init_context->current.td2d++;
+ init_context->current.tdt++;
}
-static void planeTrackToTransData(const int framenr,
- TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void planeTrackToTransData(TransformInitContext *init_context,
+ const int framenr,
MovieTrackingPlaneTrack *plane_track,
const float aspect[2])
{
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
- int i;
- tdt->flag = plane_marker->flag;
- plane_marker->flag &= ~PLANE_MARKER_TRACKED;
+ for (int i = 0; i < 4; i++) {
+ planeMarkerToTransDataInit(
+ init_context, plane_track, plane_marker, plane_marker->corners[i], aspect);
+ }
- for (i = 0; i < 4; i++) {
- planeMarkerToTransDataInit(td++, td2d++, tdt++, plane_track, plane_marker->corners[i], aspect);
+ if (init_context->current.td != NULL) {
+ plane_marker->flag &= ~PLANE_MARKER_TRACKED;
+ }
+}
+
+static void planeTrackToTransDataIfNeeded(TransformInitContext *init_context,
+ const int framenr,
+ MovieTrackingPlaneTrack *plane_track,
+ const float aspect[2])
+{
+ if (!PLANE_TRACK_VIEW_SELECTED(plane_track)) {
+ return;
}
+ planeTrackToTransData(init_context, framenr, plane_track, aspect);
}
static void transDataTrackingFree(TransInfo *UNUSED(t),
@@ -284,101 +345,53 @@ static void transDataTrackingFree(TransInfo *UNUSED(t),
static void createTransTrackingTracksData(bContext *C, TransInfo *t)
{
- TransData *td;
- TransData2D *td2d;
- SpaceClip *sc = CTX_wm_space_clip(C);
- MovieClip *clip = ED_space_clip_get_clip(sc);
- ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
- ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
- MovieTrackingTrack *track;
- MovieTrackingPlaneTrack *plane_track;
- TransDataTracking *tdt;
- int framenr = ED_space_clip_get_clip_frame_number(sc);
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ const ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+ const ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
+ const int framenr = ED_space_clip_get_clip_frame_number(space_clip);
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
- /* count */
- tc->data_len = 0;
-
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- tc->data_len++; /* offset */
+ TransformInitContext init_context = {NULL};
+ init_context.space_clip = space_clip;
+ init_context.t = t;
+ init_context.tc = tc;
- if (track->flag & SELECT) {
- tc->data_len++;
- }
+ /* Count required transformation data. */
- if (track->pat_flag & SELECT) {
- tc->data_len += 4;
- }
-
- if (track->search_flag & SELECT) {
- tc->data_len += 2;
- }
- }
+ tc->data_len = 0;
- track = track->next;
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
+ trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
}
- for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
- if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
- tc->data_len += 4;
- }
+ LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
+ planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
}
if (tc->data_len == 0) {
return;
}
- td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
- td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
- "TransTracking TransData2D");
- tdt = tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataTracking),
- "TransTracking TransDataTracking");
-
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
+ tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransTracking TransData2D");
+ tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataTracking),
+ "TransTracking TransDataTracking");
tc->custom.type.free_cb = transDataTrackingFree;
- /* create actual data */
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- trackToTransData(framenr, td, td2d, tdt, track, t->aspect);
-
- /* offset */
- td++;
- td2d++;
- tdt++;
+ init_context.current.td = tc->data;
+ init_context.current.td2d = tc->data_2d;
+ init_context.current.tdt = tc->custom.type.data;
- if (track->flag & SELECT) {
- td++;
- td2d++;
- tdt++;
- }
-
- if (track->pat_flag & SELECT) {
- td += 4;
- td2d += 4;
- tdt += 4;
- }
+ /* Create actual transformation data. */
- if (track->search_flag & SELECT) {
- td += 2;
- td2d += 2;
- tdt += 2;
- }
- }
-
- track = track->next;
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
+ trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
}
- for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
- if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
- planeTrackToTransData(framenr, td, td2d, tdt, plane_track, t->aspect);
- td += 4;
- td2d += 4;
- tdt += 4;
- }
+ LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
+ planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
}
}
@@ -560,17 +573,17 @@ void createTransTrackingData(bContext *C, TransInfo *t)
static void cancelTransTracking(TransInfo *t)
{
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
- SpaceClip *sc = t->area->spacedata.first;
- int i, framenr = ED_space_clip_get_clip_frame_number(sc);
TransDataTracking *tdt_array = tc->custom.type.data;
- i = 0;
+ int i = 0;
while (i < tc->data_len) {
TransDataTracking *tdt = &tdt_array[i];
if (tdt->mode == transDataTracking_ModeTracks) {
MovieTrackingTrack *track = tdt->track;
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+ MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, tdt->framenr);
+
+ BLI_assert(marker != NULL);
marker->flag = tdt->flag;
@@ -606,7 +619,10 @@ static void cancelTransTracking(TransInfo *t)
}
else if (tdt->mode == transDataTracking_ModePlaneTracks) {
MovieTrackingPlaneTrack *plane_track = tdt->plane_track;
- MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track,
+ tdt->framenr);
+
+ BLI_assert(plane_marker != NULL);
plane_marker->flag = tdt->flag;
i += 3;
diff --git a/source/blender/editors/transform/transform_data.h b/source/blender/editors/transform/transform_data.h
index b59197fcd39..5b01433c96b 100644
--- a/source/blender/editors/transform/transform_data.h
+++ b/source/blender/editors/transform/transform_data.h
@@ -122,11 +122,11 @@ typedef struct TransDataCurveHandleFlags {
typedef struct TransData {
TRANSDATABASIC;
- /** Distance needed to affect element (for Proportionnal Editing). */
+ /** Distance needed to affect element (for Proportional Editing). */
float dist;
- /** Distance to the nearest element (for Proportionnal Editing). */
+ /** Distance to the nearest element (for Proportional Editing). */
float rdist;
- /** Factor of the transformation (for Proportionnal Editing). */
+ /** Factor of the transformation (for Proportional Editing). */
float factor;
/** Value pointer for special transforms. */
float *val;
@@ -141,11 +141,11 @@ typedef struct TransData {
struct Object *ob;
/** For objects/bones, the first constraint in its constraint stack. */
struct bConstraint *con;
- /** For objects, poses. 1 single malloc per TransInfo! */
+ /** For objects, poses. 1 single allocation per #TransInfo! */
TransDataExtension *ext;
/** for curves, stores handle flags for modification/cancel. */
TransDataCurveHandleFlags *hdata;
- /** If set, copy of Object or PoseChannel protection. */
+ /** If set, copy of Object or #bPoseChannel protection. */
short protectflag;
} TransData;
diff --git a/source/blender/editors/transform/transform_draw_cursors.c b/source/blender/editors/transform/transform_draw_cursors.c
index 84fc45e2b45..ead8eae0997 100644
--- a/source/blender/editors/transform/transform_draw_cursors.c
+++ b/source/blender/editors/transform/transform_draw_cursors.c
@@ -45,99 +45,45 @@ enum eArrowDirection {
RIGHT,
};
-struct ArrowDims {
- int offset;
- int length;
- int size;
-};
-
-#define POS_INDEX 0
-/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions
- * private to this file - merwin
- */
+#define ARROW_WIDTH (2.0f * U.pixelsize)
+#define DASH_WIDTH (1.0f)
+#define DASH_LENGTH (8.0f * DASH_WIDTH * U.pixelsize)
-static void drawArrow(enum eArrowDirection dir, const struct ArrowDims *arrow_dims)
+static void drawArrow(const uint pos_id, const enum eArrowDirection dir)
{
- int offset = arrow_dims->offset;
- int length = arrow_dims->length;
- int size = arrow_dims->size;
-
- immBegin(GPU_PRIM_LINES, 6);
-
- switch (dir) {
- case LEFT:
- offset = -offset;
- length = -length;
- size = -size;
- ATTR_FALLTHROUGH;
- case RIGHT:
- immVertex2f(POS_INDEX, offset, 0);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length - size, -size);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length - size, size);
- break;
-
- case DOWN:
- offset = -offset;
- length = -length;
- size = -size;
- ATTR_FALLTHROUGH;
- case UP:
- immVertex2f(POS_INDEX, 0, offset);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, -size, offset + length - size);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, size, offset + length - size);
- break;
+ int offset = 5.0f * UI_DPI_FAC;
+ int length = (6.0f * UI_DPI_FAC) + (4.0f * U.pixelsize);
+ int size = (3.0f * UI_DPI_FAC) + (2.0f * U.pixelsize);
+
+ /* To line up the arrow point nicely, one end has to be extended by half its width. But
+ * being on a 45 degree angle, Pythagoras says a movement of sqrt(2)/2 * (line width /2) */
+ float adjust = (M_SQRT2 * ARROW_WIDTH / 4.0f);
+
+ if (ELEM(dir, LEFT, DOWN)) {
+ offset = -offset;
+ length = -length;
+ size = -size;
+ adjust = -adjust;
}
- immEnd();
-}
-
-static void drawArrowHead(enum eArrowDirection dir, int size)
-{
- immBegin(GPU_PRIM_LINES, 4);
-
- switch (dir) {
- case LEFT:
- size = -size;
- ATTR_FALLTHROUGH;
- case RIGHT:
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, -size);
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, size);
- break;
+ immBegin(GPU_PRIM_LINES, 6);
- case DOWN:
- size = -size;
- ATTR_FALLTHROUGH;
- case UP:
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, -size);
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, size, -size);
- break;
+ if (ELEM(dir, LEFT, RIGHT)) {
+ immVertex2f(pos_id, offset, 0);
+ immVertex2f(pos_id, offset + length, 0);
+ immVertex2f(pos_id, offset + length + adjust, adjust);
+ immVertex2f(pos_id, offset + length - size, -size);
+ immVertex2f(pos_id, offset + length, 0);
+ immVertex2f(pos_id, offset + length - size, size);
}
-
- immEnd();
-}
-
-static void drawArc(float angle_start, float angle_end, int segments, float size)
-{
- float delta = (angle_end - angle_start) / segments;
- float angle;
- int a;
-
- immBegin(GPU_PRIM_LINE_STRIP, segments + 1);
-
- for (angle = angle_start, a = 0; a < segments; angle += delta, a++) {
- immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size);
+ else {
+ immVertex2f(pos_id, 0, offset);
+ immVertex2f(pos_id, 0, offset + length);
+ immVertex2f(pos_id, adjust, offset + length + adjust);
+ immVertex2f(pos_id, -size, offset + length - size);
+ immVertex2f(pos_id, 0, offset + length);
+ immVertex2f(pos_id, size, offset + length - size);
}
- immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size);
immEnd();
}
@@ -149,11 +95,7 @@ static void drawArc(float angle_start, float angle_end, int segments, float size
bool transform_draw_cursor_poll(bContext *C)
{
ARegion *region = CTX_wm_region(C);
-
- if (region && region->regiontype == RGN_TYPE_WINDOW) {
- return 1;
- }
- return 0;
+ return (region && region->regiontype == RGN_TYPE_WINDOW) ? 1 : 0;
}
/**
@@ -164,181 +106,117 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd
{
TransInfo *t = (TransInfo *)customdata;
- if (t->helpline != HLP_NONE) {
- struct ArrowDims arrow_dims = {
- .offset = 5 * UI_DPI_FAC,
- .length = 10 * UI_DPI_FAC,
- .size = 5 * UI_DPI_FAC,
- };
-
- float cent[2];
- const float mval[3] = {x, y, 0.0f};
- float tmval[2] = {
- (float)t->mval[0],
- (float)t->mval[1],
- };
-
- projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
- /* Offset the values for the area region. */
- const float offset[2] = {
- t->region->winrct.xmin,
- t->region->winrct.ymin,
- };
-
- for (int i = 0; i < 2; i++) {
- cent[i] += offset[i];
- tmval[i] += offset[i];
- }
-
- GPU_line_smooth(true);
- GPU_blend(GPU_BLEND_ALPHA);
-
- GPU_matrix_push();
-
- /* Dashed lines first. */
- if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
- const uint shdr_pos = GPU_vertformat_attr_add(
- immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */
- BLI_assert(shdr_pos == POS_INDEX);
+ if (t->helpline == HLP_NONE) {
+ return;
+ }
- GPU_line_width(1.0f);
+ float cent[2];
+ const float mval[3] = {x, y, 0.0f};
+ float tmval[2] = {
+ (float)t->mval[0],
+ (float)t->mval[1],
+ };
+
+ projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
+ /* Offset the values for the area region. */
+ const float offset[2] = {
+ t->region->winrct.xmin,
+ t->region->winrct.ymin,
+ };
+
+ for (int i = 0; i < 2; i++) {
+ cent[i] += offset[i];
+ tmval[i] += offset[i];
+ }
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+
+ GPU_line_smooth(true);
+ GPU_blend(GPU_BLEND_ALPHA);
+ const uint pos_id = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ /* Dashed lines first. */
+ if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
+ GPU_line_width(DASH_WIDTH);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniformThemeColor3(TH_VIEW_OVERLAY);
+ immUniform1f("dash_width", DASH_LENGTH);
+ immUniform1f("dash_factor", 0.5f);
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2fv(pos_id, cent);
+ immVertex2f(pos_id, tmval[0], tmval[1]);
+ immEnd();
+ immUnbindProgram();
+ }
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ /* And now, solid lines. */
- immUniform1i("colors_len", 0); /* "simple" mode */
- immUniformThemeColor3(TH_VIEW_OVERLAY);
- immUniform1f("dash_width", 6.0f * UI_DPI_FAC);
- immUniform1f("dash_factor", 0.5f);
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
+ immUniformThemeColor3(TH_VIEW_OVERLAY);
+ immUniform2fv("viewportSize", &viewport_size[2]);
+ immUniform1f("lineWidth", ARROW_WIDTH);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2fv(POS_INDEX, cent);
- immVertex2f(POS_INDEX, tmval[0], tmval[1]);
- immEnd();
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(mval);
- immUnbindProgram();
+ switch (t->helpline) {
+ case HLP_SPRING:
+ GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
+ drawArrow(pos_id, UP);
+ drawArrow(pos_id, DOWN);
+ break;
+ case HLP_HARROW:
+ drawArrow(pos_id, RIGHT);
+ drawArrow(pos_id, LEFT);
+ break;
+ case HLP_VARROW:
+ drawArrow(pos_id, UP);
+ drawArrow(pos_id, DOWN);
+ break;
+ case HLP_CARROW: {
+ /* Draw arrow based on direction defined by custom-points. */
+ const int *data = t->mouse.data;
+ const float angle = -atan2f(data[2] - data[0], data[3] - data[1]);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
+ drawArrow(pos_id, UP);
+ drawArrow(pos_id, DOWN);
+ break;
}
-
- /* And now, solid lines. */
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- UNUSED_VARS_NDEBUG(pos); /* silence warning */
- BLI_assert(pos == POS_INDEX);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- switch (t->helpline) {
- case HLP_SPRING:
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3fv(mval);
- GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
-
- GPU_line_width(3.0f);
- drawArrow(UP, &arrow_dims);
- drawArrow(DOWN, &arrow_dims);
- break;
- case HLP_HARROW:
- immUniformThemeColor3(TH_VIEW_OVERLAY);
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
- drawArrow(RIGHT, &arrow_dims);
- drawArrow(LEFT, &arrow_dims);
- break;
- case HLP_VARROW:
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
- drawArrow(UP, &arrow_dims);
- drawArrow(DOWN, &arrow_dims);
- break;
- case HLP_CARROW: {
- /* Draw arrow based on direction defined by custom-points. */
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
-
- const int *data = t->mouse.data;
- const float dx = data[2] - data[0], dy = data[3] - data[1];
- const float angle = -atan2f(dx, dy);
-
- GPU_matrix_push();
-
- GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
-
- drawArrow(UP, &arrow_dims);
- drawArrow(DOWN, &arrow_dims);
-
- GPU_matrix_pop();
- break;
- }
- case HLP_ANGLE: {
- float dx = tmval[0] - cent[0], dy = tmval[1] - cent[1];
- float angle = atan2f(dy, dx);
- float dist = hypotf(dx, dy);
- float delta_angle = min_ff(15.0f / (dist / UI_DPI_FAC), (float)M_PI / 4.0f);
- float spacing_angle = min_ff(5.0f / (dist / UI_DPI_FAC), (float)M_PI / 12.0f);
-
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0);
-
- GPU_line_width(3.0f);
- drawArc(angle - delta_angle, angle - spacing_angle, 10, dist);
- drawArc(angle + spacing_angle, angle + delta_angle, 10, dist);
-
- GPU_matrix_push();
-
- GPU_matrix_translate_3f(
- cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
- GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z');
-
- drawArrowHead(DOWN, arrow_dims.size);
-
- GPU_matrix_pop();
-
- GPU_matrix_translate_3f(
- cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
- GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z');
-
- drawArrowHead(UP, arrow_dims.size);
- break;
- }
- case HLP_TRACKBALL: {
- uchar col[3], col2[3];
- UI_GetThemeColor3ubv(TH_GRID, col);
-
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
-
- UI_make_axis_color(col, col2, 'X');
- immUniformColor3ubv(col2);
-
- drawArrow(RIGHT, &arrow_dims);
- drawArrow(LEFT, &arrow_dims);
-
- UI_make_axis_color(col, col2, 'Y');
- immUniformColor3ubv(col2);
-
- drawArrow(UP, &arrow_dims);
- drawArrow(DOWN, &arrow_dims);
- break;
- }
+ case HLP_ANGLE: {
+ GPU_matrix_push();
+ float angle = atan2f(tmval[1] - cent[1], tmval[0] - cent[0]);
+ GPU_matrix_translate_3f(cosf(angle), sinf(angle), 0);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
+ drawArrow(pos_id, DOWN);
+ GPU_matrix_pop();
+ GPU_matrix_translate_3f(cosf(angle), sinf(angle), 0);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
+ drawArrow(pos_id, UP);
+ break;
}
-
- immUnbindProgram();
- GPU_matrix_pop();
-
- GPU_line_smooth(false);
- GPU_blend(GPU_BLEND_NONE);
+ case HLP_TRACKBALL: {
+ uchar col[3], col2[3];
+ UI_GetThemeColor3ubv(TH_GRID, col);
+ UI_make_axis_color(col, col2, 'X');
+ immUniformColor3ubv(col2);
+ drawArrow(pos_id, RIGHT);
+ drawArrow(pos_id, LEFT);
+ UI_make_axis_color(col, col2, 'Y');
+ immUniformColor3ubv(col2);
+ drawArrow(pos_id, UP);
+ drawArrow(pos_id, DOWN);
+ break;
+ }
+ case HLP_NONE:
+ break;
}
+
+ GPU_matrix_pop();
+ immUnbindProgram();
+ GPU_line_smooth(false);
+ GPU_blend(GPU_BLEND_NONE);
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index b092b3e3e0b..6fca49495e9 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -26,7 +26,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_gpencil_types.h"
-#include "DNA_mesh_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
@@ -44,6 +43,7 @@
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_mask.h"
+#include "BKE_modifier.h"
#include "BKE_paint.h"
#include "ED_clip.h"
@@ -119,79 +119,6 @@ void resetTransRestrictions(TransInfo *t)
t->flag &= ~T_ALL_RESTRICTIONS;
}
-void initTransDataContainers_FromObjectData(TransInfo *t,
- Object *obact,
- Object **objects,
- uint objects_len)
-{
- const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
- const short object_type = obact ? obact->type : -1;
-
- if ((object_mode & OB_MODE_EDIT) || (t->options & CTX_GPENCIL_STROKES) ||
- ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE))) {
- if (t->data_container) {
- MEM_freeN(t->data_container);
- }
-
- bool free_objects = false;
- if (objects == NULL) {
- objects = BKE_view_layer_array_from_objects_in_mode(
- t->view_layer,
- (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
- &objects_len,
- {
- .object_mode = object_mode,
- .no_dup_data = true,
- });
- free_objects = true;
- }
-
- t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__);
- t->data_container_len = objects_len;
-
- for (int i = 0; i < objects_len; i++) {
- TransDataContainer *tc = &t->data_container[i];
- if (((t->flag & T_NO_MIRROR) == 0) && ((t->options & CTX_NO_MIRROR) == 0) &&
- (objects[i]->type == OB_MESH)) {
- tc->use_mirror_axis_x = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_X) != 0;
- tc->use_mirror_axis_y = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Y) != 0;
- tc->use_mirror_axis_z = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Z) != 0;
- }
-
- if (object_mode & OB_MODE_EDIT) {
- tc->obedit = objects[i];
- /* Check needed for UV's */
- if ((t->flag & T_2D_EDIT) == 0) {
- tc->use_local_mat = true;
- }
- }
- else if (object_mode & OB_MODE_POSE) {
- tc->poseobj = objects[i];
- tc->use_local_mat = true;
- }
- else if (t->options & CTX_GPENCIL_STROKES) {
- tc->use_local_mat = true;
- }
-
- if (tc->use_local_mat) {
- BLI_assert((t->flag & T_2D_EDIT) == 0);
- copy_m4_m4(tc->mat, objects[i]->obmat);
- copy_m3_m4(tc->mat3, tc->mat);
- /* for non-invertible scale matrices, invert_m4_m4_fallback()
- * can still provide a valid pivot */
- invert_m4_m4_fallback(tc->imat, tc->mat);
- invert_m3_m3(tc->imat3, tc->mat3);
- normalize_m3_m3(tc->mat3_unit, tc->mat3);
- }
- /* Otherwise leave as zero. */
- }
-
- if (free_objects) {
- MEM_freeN(objects);
- }
- }
-}
-
/**
* Setup internal data, mouse, vectors
*
@@ -225,7 +152,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->flag = 0;
- if (obact && !(t->options & (CTX_CURSOR | CTX_TEXTURE)) &&
+ if (obact && !(t->options & (CTX_CURSOR | CTX_TEXTURE_SPACE)) &&
ELEM(object_mode, OB_MODE_EDIT, OB_MODE_EDIT_GPENCIL)) {
t->obedit_type = obact->type;
}
@@ -272,7 +199,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
/* Crease needs edge flag */
if (ELEM(t->mode, TFM_CREASE, TFM_BWEIGHT)) {
- t->options |= CTX_EDGE;
+ t->options |= CTX_EDGE_DATA;
}
t->remove_on_cancel = false;
@@ -1110,7 +1037,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
return true;
}
}
- else if (t->flag & T_POSE) {
+ else if (t->options & CTX_POSE_BONE) {
ViewLayer *view_layer = t->view_layer;
Object *ob = OBACT(view_layer);
if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
@@ -1184,20 +1111,13 @@ void calculateCenter(TransInfo *t)
}
calculateCenterLocal(t, t->center_global);
- /* avoid calculating again */
- {
- TransCenterData *cd = &t->center_cache[t->around];
- copy_v3_v3(cd->global, t->center_global);
- cd->is_set = true;
- }
-
calculateCenter2D(t);
- /* for panning from cameraview */
- if ((t->flag & T_OBJECT) && (t->flag & T_OVERRIDE_CENTER) == 0) {
+ /* For panning from the camera-view. */
+ if ((t->options & CTX_OBJECT) && (t->flag & T_OVERRIDE_CENTER) == 0) {
if (t->spacetype == SPACE_VIEW3D && t->region && t->region->regiontype == RGN_TYPE_WINDOW) {
- if (t->flag & T_CAMERA) {
+ if (t->options & CTX_CAMERA) {
float axis[3];
/* persinv is nasty, use viewinv instead, always right */
copy_v3_v3(axis, t->viewinv[2]);
@@ -1237,23 +1157,6 @@ void calculateCenter(TransInfo *t)
}
}
-BLI_STATIC_ASSERT(ARRAY_SIZE(((TransInfo *)NULL)->center_cache) == (V3D_AROUND_ACTIVE + 1),
- "test size");
-
-/**
- * Lazy initialize transform center data, when we need to access center values from other types.
- */
-const TransCenterData *transformCenter_from_type(TransInfo *t, int around)
-{
- BLI_assert(around <= V3D_AROUND_ACTIVE);
- TransCenterData *cd = &t->center_cache[around];
- if (cd->is_set == false) {
- calculateCenter_FromAround(t, around, cd->global);
- cd->is_set = true;
- }
- return cd;
-}
-
void calculatePropRatio(TransInfo *t)
{
int i;
@@ -1416,7 +1319,7 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
if (td->ext->rotOrder == ROT_MODE_QUAT) {
float quat[4];
- /* calculate the total rotatation */
+ /* Calculate the total rotation. */
quat_to_mat3(obmat, td->ext->iquat);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
@@ -1437,7 +1340,7 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
float axis[3], angle;
- /* calculate the total rotatation */
+ /* Calculate the total rotation. */
axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
@@ -1459,7 +1362,7 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
else {
float eul[3];
- /* calculate the total rotatation */
+ /* Calculate the total rotation. */
eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
@@ -1478,3 +1381,23 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
copy_v3_v3(td->ext->rot, eul);
}
}
+
+Object *transform_object_deform_pose_armature_get(const TransInfo *t, Object *ob)
+{
+ if (!(ob->mode & OB_MODE_ALL_WEIGHT_PAINT)) {
+ return NULL;
+ }
+ /* Important that ob_armature can be set even when its not selected T23412.
+ * 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) {
+ Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature);
+ if (base_arm) {
+ View3D *v3d = t->view;
+ if (BASE_VISIBLE(v3d, base_arm)) {
+ return ob_armature;
+ }
+ }
+ }
+ return NULL;
+}
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 9c08159cf07..27df29afd8d 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -532,7 +532,7 @@ static void protectflag_to_drawflags_ebone(RegionView3D *rv3d, const EditBone *e
/* could move into BLI_math however this is only useful for display/editing purposes */
static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
{
- /* X/Y are arbitrary axies, most importantly Z is the axis of rotation */
+ /* X/Y are arbitrary axes, most importantly Z is the axis of rotation. */
float cross_vec[3];
float quat[4];
@@ -704,7 +704,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
/* skip strokes that are invalid for current view */
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 70ef5fcde7a..bfeb96d18c4 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -499,28 +499,4 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp
}
}
-eRedrawFlag handleMouseInput(TransInfo *t, MouseInput *mi, const wmEvent *event)
-{
- eRedrawFlag redraw = TREDRAW_NOTHING;
-
- switch (event->type) {
- case EVT_LEFTSHIFTKEY:
- case EVT_RIGHTSHIFTKEY:
- if (event->val == KM_PRESS) {
- t->modifiers |= MOD_PRECISION;
- /* shift is modifier for higher precision transforn */
- mi->precision = 1;
- redraw = TREDRAW_HARD;
- }
- else if (event->val == KM_RELEASE) {
- t->modifiers &= ~MOD_PRECISION;
- mi->precision = 0;
- redraw = TREDRAW_HARD;
- }
- break;
- }
-
- return redraw;
-}
-
/** \} */
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index a4d999b868d..9e6e4d8807e 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -70,7 +70,7 @@ int transform_mode_really_used(bContext *C, int mode)
bool transdata_check_local_center(TransInfo *t, short around)
{
return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
- ((t->flag & (T_OBJECT | T_POSE)) ||
+ ((t->options & (CTX_OBJECT | CTX_POSE_BONE)) ||
/* implicit: (t->flag & T_EDIT) */
(ELEM(t->obedit_type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE, OB_GPENCIL)) ||
(t->spacetype == SPACE_GRAPH) ||
@@ -513,7 +513,7 @@ void constraintSizeLim(TransInfo *t, TransData *td)
return;
}
- /* extrace scale from matrix and apply back sign */
+ /* Extract scale from matrix and apply back sign. */
mat4_to_size(td->ext->size, cob.matrix);
mul_v3_v3(td->ext->size, size_sign);
}
@@ -629,7 +629,7 @@ void ElementRotation_ex(TransInfo *t,
* matrix (and inverse). That is not all though. Once the proper translation
* has been computed, it has to be converted back into the bone's space.
*/
- else if (t->flag & T_POSE) {
+ else if (t->options & CTX_POSE_BONE) {
/* Extract and invert armature object matrix */
if ((td->flag & TD_NO_LOC) == 0) {
@@ -705,7 +705,7 @@ void ElementRotation_ex(TransInfo *t,
mul_m3_m3m3(totmat, mat, td->ext->r_mtx);
mul_m3_m3m3(smat, td->ext->r_smtx, totmat);
- /* calculate the total rotatation in eulers */
+ /* Calculate the total rotation in eulers. */
copy_v3_v3(eul, td->ext->irot);
eulO_to_mat3(eulmat, eul, td->ext->rotOrder);
@@ -778,7 +778,7 @@ void ElementRotation_ex(TransInfo *t,
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
- /* calculate the total rotatation in eulers */
+ /* Calculate the total rotation in eulers. */
add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* correct for delta rot */
eulO_to_mat3(obmat, eul, td->ext->rotOrder);
/* mat = transform, obmat = object rotation */
@@ -902,7 +902,7 @@ static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float
mat3_to_rot_size(rmat, size, mat);
- /* first tried with dotproduct... but the sign flip is crucial */
+ /* First tried with dot-product... but the sign flip is crucial. */
if (dot_v3v3(rmat[0], smat[0]) < 0.0f) {
size[0] = -size[0];
}
@@ -1026,7 +1026,7 @@ void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float ma
mul_v3_fl(vec, td->factor);
}
- if (t->flag & (T_OBJECT | T_POSE)) {
+ if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
mul_m3_v3(td->smtx, vec);
}
diff --git a/source/blender/editors/transform/transform_mode_align.c b/source/blender/editors/transform/transform_mode_align.c
index f16021914f1..5bc2aa68443 100644
--- a/source/blender/editors/transform/transform_mode_align.c
+++ b/source/blender/editors/transform/transform_mode_align.c
@@ -55,7 +55,7 @@ static void applyAlign(TransInfo *t, const int UNUSED(mval[2]))
}
/* around local centers */
- if (t->flag & (T_OBJECT | T_POSE)) {
+ if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
copy_v3_v3(tc->center_local, td->center);
}
else {
diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
index 7ccfd0149bd..4330d5e79be 100644
--- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
@@ -35,10 +35,12 @@
#include "WM_types.h"
#include "UI_interface.h"
+#include "UI_view2d.h"
#include "BLT_translation.h"
#include "transform.h"
+#include "transform_convert.h"
#include "transform_mode.h"
#include "transform_snap.h"
@@ -49,9 +51,9 @@
static eRedrawFlag seq_slide_handleEvent(struct TransInfo *t, const wmEvent *event)
{
BLI_assert(t->mode == TFM_SEQ_SLIDE);
- wmKeyMapItem *kmi = t->custom.mode.data;
+ const wmKeyMapItem *kmi = t->custom.mode.data;
if (kmi && event->type == kmi->type && event->val == kmi->val) {
- /* Allows the 'Expand to fit' effect to be enabled as a toogle. */
+ /* Allows the "Expand to Fit" effect to be enabled as a toggle. */
t->flag ^= T_ALT_TRANSFORM;
return TREDRAW_HARD;
}
@@ -73,7 +75,7 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA
ofs += BLI_snprintf(
str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
- wmKeyMapItem *kmi = t->custom.mode.data;
+ const wmKeyMapItem *kmi = t->custom.mode.data;
if (kmi) {
ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs);
}
@@ -106,6 +108,7 @@ static void applySeqSlide(TransInfo *t, const int mval[2])
float values_final[3] = {0.0f};
snapSequenceBounds(t, mval);
+ transform_convert_sequencer_channel_clamp(t);
if (applyNumInput(&t->num, values_final)) {
if (t->con.mode & CON_APPLY) {
if (t->con.mode & CON_AXIS0) {
@@ -158,7 +161,7 @@ void initSeqSlide(TransInfo *t)
if (t->keymap) {
/* Workaround to use the same key as the modal keymap. */
- t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
+ t->custom.mode.data = (void *)WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
}
}
/** \} */
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index dae3fe6f7b4..dff9ded6b29 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -143,7 +143,7 @@ static BMEdge *get_other_edge(BMVert *v, BMEdge *e)
return NULL;
}
-/* interpoaltes along a line made up of 2 segments (used for edge slide) */
+/* Interpolates along a line made up of 2 segments (used for edge slide). */
static void interp_line_v3_v3v3v3(
float p[3], const float v1[3], const float v2[3], const float v3[3], float t)
{
diff --git a/source/blender/editors/transform/transform_mode_mirror.c b/source/blender/editors/transform/transform_mode_mirror.c
index 3aa99975fda..9891af8b9a4 100644
--- a/source/blender/editors/transform/transform_mode_mirror.c
+++ b/source/blender/editors/transform/transform_mode_mirror.c
@@ -152,7 +152,7 @@ static void ElementMirror(TransInfo *t, TransDataContainer *tc, TransData *td, i
sub_v3_v3(vec, td->center);
}
- if (t->flag & (T_OBJECT | T_POSE)) {
+ if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
mul_m3_v3(td->smtx, vec);
}
diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c
index 62a4fbd6f04..4d0bb7fbe9c 100644
--- a/source/blender/editors/transform/transform_mode_resize.c
+++ b/source/blender/editors/transform/transform_mode_resize.c
@@ -132,7 +132,7 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
}
}
- /* evil hack - redo resize if cliping needed */
+ /* Evil hack - redo resize if clipping needed. */
if (t->flag & T_CLIP_UV && clipUVTransform(t, t->values_final, 1)) {
size_to_mat3(mat, t->values_final);
diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c
index ba5b1229f3e..6e497d85417 100644
--- a/source/blender/editors/transform/transform_mode_shrink_fatten.c
+++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c
@@ -49,9 +49,9 @@
static eRedrawFlag shrinkfatten_handleEvent(struct TransInfo *t, const wmEvent *event)
{
BLI_assert(t->mode == TFM_SHRINKFATTEN);
- wmKeyMapItem *kmi = t->custom.mode.data;
+ const wmKeyMapItem *kmi = t->custom.mode.data;
if (kmi && event->type == kmi->type && event->val == kmi->val) {
- /* Allows the 'Even Thickness' effect to be enabled as a toogle. */
+ /* Allows the "Even Thickness" effect to be enabled as a toggle. */
t->flag ^= T_ALT_TRANSFORM;
return TREDRAW_HARD;
}
@@ -84,8 +84,13 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
else {
/* default header print */
if (unit != NULL) {
- ofs += BKE_unit_value_as_string(
- str + ofs, sizeof(str) - ofs, distance * unit->scale_length, 4, B_UNIT_LENGTH, unit, true);
+ ofs += BKE_unit_value_as_string(str + ofs,
+ sizeof(str) - ofs,
+ distance * unit->scale_length,
+ 4,
+ B_UNIT_LENGTH,
+ unit,
+ true);
}
else {
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, "%.4f", distance);
@@ -97,7 +102,7 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
}
ofs += BLI_strncpy_rlen(str + ofs, ", (", sizeof(str) - ofs);
- wmKeyMapItem *kmi = t->custom.mode.data;
+ const wmKeyMapItem *kmi = t->custom.mode.data;
if (kmi) {
ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs);
}
@@ -157,7 +162,7 @@ void initShrinkFatten(TransInfo *t)
if (t->keymap) {
/* Workaround to use the same key as the modal keymap. */
- t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
+ t->custom.mode.data = (void *)WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
}
}
}
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 851e0feb5f5..41fc6ee0aaf 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -294,7 +294,7 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
const float *original_normal;
/* In pose mode, we want to align normals with Y axis of bones... */
- if (t->flag & T_POSE) {
+ if (t->options & CTX_POSE_BONE) {
original_normal = td->axismtx[1];
}
else {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 15c215c426d..01c00247a7a 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -411,7 +411,7 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
int exit_code;
TransInfo *t = op->customdata;
- const enum TfmMode mode_prev = t->mode;
+ const eTfmMode mode_prev = t->mode;
#if defined(WITH_INPUT_NDOF) && 0
/* Stable 2D mouse coords map to different 3D coords while the 3D mouse is active
@@ -432,7 +432,7 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
* since we're not reading from 'td->center' in this case. see: T40241 */
if (t->tsnap.target == SCE_SNAP_TARGET_ACTIVE) {
/* In camera view, tsnap callback is not set
- * (see initSnappingMode() in transfrom_snap.c, and T40348). */
+ * (see #initSnappingMode() in transform_snap.c, and T40348). */
if (t->tsnap.targetSnap && ((t->tsnap.status & TARGET_INIT) == 0)) {
t->tsnap.targetSnap(t);
}
@@ -444,7 +444,7 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
transformops_exit(C, op);
- exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
+ exit_code &= ~OPERATOR_PASS_THROUGH; /* Preventively remove pass-through. */
}
else {
if (mode_prev != t->mode) {
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 3b39f4d06ad..1470d3b7059 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -521,23 +521,19 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
const int pivot_point)
{
switch (orientation_type) {
- case V3D_ORIENT_GLOBAL: {
- unit_m3(r_mat);
- return V3D_ORIENT_GLOBAL;
- }
case V3D_ORIENT_GIMBAL: {
if (ob && gimbal_axis(ob, r_mat)) {
- return V3D_ORIENT_GIMBAL;
+ break;
}
- /* if not gimbal, fall through to normal */
+ /* If not gimbal, fall through to normal. */
ATTR_FALLTHROUGH;
}
case V3D_ORIENT_NORMAL: {
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
ED_getTransformOrientationMatrix(C, ob, obedit, pivot_point, r_mat);
- return V3D_ORIENT_NORMAL;
+ break;
}
- /* no break we define 'normal' as 'local' in Object mode */
+ /* No break we define 'normal' as 'local' in Object mode. */
ATTR_FALLTHROUGH;
}
case V3D_ORIENT_LOCAL: {
@@ -552,10 +548,14 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
else {
transform_orientations_create_from_axis(r_mat, UNPACK3(ob->obmat));
}
- return V3D_ORIENT_LOCAL;
+ break;
}
+ /* If not local, fall through to global. */
+ ATTR_FALLTHROUGH;
+ }
+ case V3D_ORIENT_GLOBAL: {
unit_m3(r_mat);
- return V3D_ORIENT_GLOBAL;
+ break;
}
case V3D_ORIENT_VIEW: {
if (rv3d != NULL) {
@@ -565,11 +565,11 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
else {
unit_m3(r_mat);
}
- return V3D_ORIENT_VIEW;
+ break;
}
case V3D_ORIENT_CURSOR: {
BKE_scene_cursor_rot_to_mat3(&scene->cursor, r_mat);
- return V3D_ORIENT_CURSOR;
+ break;
}
case V3D_ORIENT_CUSTOM_MATRIX: {
/* Do nothing. */;
@@ -609,6 +609,12 @@ short transform_orientation_matrix_get(
orientation_index_custom = orientation - V3D_ORIENT_CUSTOM;
orientation = V3D_ORIENT_CUSTOM;
}
+ else if (ob && (ob->mode & OB_MODE_ALL_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
+ Object *ob_armature = transform_object_deform_pose_armature_get(t, ob);
+ if (ob_armature) {
+ ob = ob_armature;
+ }
+ }
if ((t->spacetype == SPACE_VIEW3D) && t->region && (t->region->regiontype == RGN_TYPE_WINDOW)) {
rv3d = t->region->regiondata;
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index c19dd4598cf..6d04de34016 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -235,7 +235,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_IMAGE) {
if (validSnap(t)) {
- /* This will not draw, and Im nor sure why - campbell */
+ /* This will not draw, and I'm nor sure why - campbell */
/* TODO: see 2.7x for non-working code */
}
}
@@ -299,83 +299,93 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
void applyProject(TransInfo *t)
{
- /* XXX FLICKER IN OBJECT MODE */
- if ((t->tsnap.project) && activeSnap(t) && (t->flag & T_NO_PROJECT) == 0) {
- float tvec[3];
- int i;
+ if (!t->tsnap.project) {
+ return;
+ }
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- float iloc[3], loc[3], no[3];
- float mval_fl[2];
- if (td->flag & TD_SKIP) {
- continue;
- }
+ if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) {
+ return;
+ }
- if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
- continue;
- }
+ if (doForceIncrementSnap(t)) {
+ return;
+ }
- copy_v3_v3(iloc, td->loc);
- if (tc->use_local_mat) {
- mul_m4_v3(tc->mat, iloc);
- }
- else if (t->flag & T_OBJECT) {
- BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
- copy_v3_v3(iloc, td->ob->obmat[3]);
- }
+ float tvec[3];
+ int i;
- if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
- V3D_PROJ_RET_OK) {
- if (ED_transform_snap_object_project_view3d(
- t->tsnap.object_context,
- t->depsgraph,
- SCE_SNAP_MODE_FACE,
- &(const struct SnapObjectParams){
- .snap_select = t->tsnap.modeSelect,
- .use_object_edit_cage = (t->flag & T_EDIT) != 0,
- .use_occlusion_test = false,
- .use_backface_culling = t->tsnap.use_backface_culling,
- },
- mval_fl,
- NULL,
- 0,
- loc,
- no)) {
+ /* XXX FLICKER IN OBJECT MODE */
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ float iloc[3], loc[3], no[3];
+ float mval_fl[2];
+ 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]);
+ }
+
+ if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
+ V3D_PROJ_RET_OK) {
+ if (ED_transform_snap_object_project_view3d(
+ t->tsnap.object_context,
+ t->depsgraph,
+ SCE_SNAP_MODE_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = t->tsnap.modeSelect,
+ .use_object_edit_cage = (t->flag & T_EDIT) != 0,
+ .use_occlusion_test = false,
+ .use_backface_culling = t->tsnap.use_backface_culling,
+ },
+ mval_fl,
+ NULL,
+ 0,
+ loc,
+ no)) {
#if 0
if (tc->use_local_mat) {
mul_m4_v3(tc->imat, loc);
}
#endif
- sub_v3_v3v3(tvec, loc, iloc);
+ sub_v3_v3v3(tvec, loc, iloc);
- mul_m3_v3(td->smtx, tvec);
+ mul_m3_v3(td->smtx, tvec);
- add_v3_v3(td->loc, tvec);
+ add_v3_v3(td->loc, tvec);
- if (t->tsnap.align && (t->flag & T_OBJECT)) {
- /* handle alignment as well */
- const float *original_normal;
- float mat[3][3];
+ if (t->tsnap.align && (t->options & CTX_OBJECT)) {
+ /* handle alignment as well */
+ const float *original_normal;
+ float mat[3][3];
- /* In pose mode, we want to align normals with Y axis of bones... */
- original_normal = td->axismtx[2];
+ /* In pose mode, we want to align normals with Y axis of bones... */
+ original_normal = td->axismtx[2];
- rotation_between_vecs_to_mat3(mat, original_normal, no);
+ rotation_between_vecs_to_mat3(mat, original_normal, no);
- transform_data_ext_rotate(td, mat, true);
+ transform_data_ext_rotate(td, mat, true);
- /* TODO support constraints for rotation too? see ElementRotation */
- }
+ /* TODO support constraints for rotation too? see ElementRotation */
}
}
+ }
-#if 0 /* TODO: sipport this? */
+#if 0 /* TODO: support this? */
constraintTransLim(t, td);
#endif
- }
}
}
}
@@ -412,7 +422,7 @@ void applyGridAbsolute(TransInfo *t)
if (tc->use_local_mat) {
mul_m4_v3(tc->mat, iloc);
}
- else if (t->flag & T_OBJECT) {
+ 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]);
}
@@ -561,7 +571,8 @@ static void initSnappingMode(TransInfo *t)
}
}
- if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && (t->flag & T_CAMERA) == 0) {
+ if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) &&
+ (t->options & CTX_CAMERA) == 0) {
/* Only 3D view or UV. */
/* Not with camera selected in camera view. */
@@ -916,6 +927,64 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
/** \name Target
* \{ */
+static void snap_target_median_impl(TransInfo *t, float r_median[3])
+{
+ int i_accum = 0;
+
+ zero_v3(r_median);
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+ int i;
+ float v[3];
+ zero_v3(v);
+
+ for (i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
+ add_v3_v3(v, td->center);
+ }
+
+ if (i == 0) {
+ /* Is this possible? */
+ continue;
+ }
+
+ mul_v3_fl(v, 1.0 / i);
+
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->mat, v);
+ }
+
+ add_v3_v3(r_median, v);
+ i_accum++;
+ }
+
+ mul_v3_fl(r_median, 1.0 / i_accum);
+
+ // 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 == TC_CURSOR_VIEW3D) {
+ /* 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) {
@@ -987,41 +1056,7 @@ static void TargetSnapMedian(TransInfo *t)
{
/* Only need to calculate once. */
if ((t->tsnap.status & TARGET_INIT) == 0) {
- int i_accum = 0;
-
- t->tsnap.snapTarget[0] = 0;
- t->tsnap.snapTarget[1] = 0;
- t->tsnap.snapTarget[2] = 0;
-
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- int i;
- float v[3];
- zero_v3(v);
-
- for (i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
- add_v3_v3(v, td->center);
- }
-
- if (i == 0) {
- /* Is this possible? */
- continue;
- }
-
- mul_v3_fl(v, 1.0 / i);
-
- if (tc->use_local_mat) {
- mul_m4_v3(tc->mat, v);
- }
-
- add_v3_v3(t->tsnap.snapTarget, v);
- i_accum++;
- }
-
- mul_v3_fl(t->tsnap.snapTarget, 1.0 / i_accum);
-
- TargetSnapOffset(t, NULL);
-
+ snap_target_median_impl(t, t->tsnap.snapTarget);
t->tsnap.status |= TARGET_INIT;
}
}
@@ -1034,7 +1069,7 @@ static void TargetSnapClosest(TransInfo *t)
TransData *closest = NULL;
/* Object mode */
- if (t->flag & T_OBJECT) {
+ if (t->options & CTX_OBJECT) {
int i;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
@@ -1421,28 +1456,10 @@ 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);
- const float *center_global = t->center_global;
+ snap_target_grid_ensure(t);
+ const float *center_global = t->tsnap.snapTargetGrid;
const float *asp = t->aspect;
- if (t->options & CTX_CURSOR) {
- /* Note that we must already have called #transformCenter_from_type, otherwise
- * we would be lazy-initializing data which is being transformed,
- * causing the transformed cursor location to be used instead of it's initial location. */
- BLI_assert(t->center_cache[V3D_AROUND_CURSOR].is_set);
-
- /* Use a fallback when transforming the cursor.
- * In this case the center is _not_ derived from the cursor which is being transformed. */
- const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CURSOR);
- center_global = cd->global;
- }
- 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. */
- const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CENTER_MEDIAN);
- center_global = cd->global;
- }
-
float in[3];
if (t->con.mode & CON_APPLY) {
BLI_assert(t->tsnap.snapElem == 0);
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index b610369f82d..58198f21ba2 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -1959,7 +1959,7 @@ static short snapCurve(SnapData *snapdata,
int clip_plane_len = snapdata->clip_plane_len;
if (snapdata->has_occlusion_plane) {
- /* We snap to vertices even if coccluded. */
+ /* We snap to vertices even if occluded. */
clip_planes++;
clip_plane_len--;
}
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 533416bf85e..baa178a6a94 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -169,16 +169,16 @@ void ED_undo_push(bContext *C, const char *str)
}
/**
- * \note Also check #undo_history_exec in bottom if you change notifiers.
+ * Common pre management of undo/redo (killing all running jobs, calling pre handlers, etc.).
*/
-static int ed_undo_step_impl(
- bContext *C, int step, const char *undoname, int undo_index, ReportList *reports)
+static void ed_undo_step_pre(bContext *C,
+ wmWindowManager *wm,
+ const enum eUndoStepDir undo_dir,
+ ReportList *reports)
{
- /* Mutually exclusives, ensure correct input. */
- BLI_assert(((undoname || undo_index != -1) && !step) ||
- (!(undoname || undo_index != -1) && step));
- CLOG_INFO(&LOG, 1, "name='%s', step=%d", undoname, step);
- wmWindowManager *wm = CTX_wm_manager(C);
+ BLI_assert(ELEM(undo_dir, STEP_UNDO, STEP_REDO));
+
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ScrArea *area = CTX_wm_area(C);
@@ -187,18 +187,12 @@ static int ed_undo_step_impl(
WM_jobs_kill_all(wm);
if (G.debug & G_DEBUG_IO) {
- Main *bmain = CTX_data_main(C);
if (bmain->lock != NULL) {
BKE_report(reports, RPT_INFO, "Checking sanity of current .blend file *BEFORE* undo step");
BLO_main_validate_libraries(bmain, reports);
}
}
- /* TODO(campbell): undo_system: use undo system */
- /* grease pencil can be can be used in plenty of spaces, so check it first */
- if (ED_gpencil_session_active()) {
- return ED_undo_gpencil_step(C, step, undoname);
- }
if (area && (area->spacetype == SPACE_VIEW3D)) {
Object *obact = CTX_data_active_object(C);
if (obact && (obact->type == OB_GPENCIL)) {
@@ -206,89 +200,40 @@ static int ed_undo_step_impl(
}
}
- UndoStep *step_data_from_name = NULL;
- int step_for_callback = step;
- if (undoname != NULL) {
- step_data_from_name = BKE_undosys_step_find_by_name(wm->undo_stack, undoname);
- if (step_data_from_name == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- /* TODO(campbell), could use simple optimization. */
- /* Pointers match on redo. */
- step_for_callback = (BLI_findindex(&wm->undo_stack->steps, step_data_from_name) <
- BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active)) ?
- 1 :
- -1;
- }
- else if (undo_index != -1) {
- step_for_callback = (undo_index <
- BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active)) ?
- 1 :
- -1;
- }
-
/* App-Handlers (pre). */
{
/* Note: ignore grease pencil for now. */
- Main *bmain = CTX_data_main(C);
wm->op_undo_depth++;
BKE_callback_exec_id(
- bmain, &scene->id, (step_for_callback > 0) ? BKE_CB_EVT_UNDO_PRE : BKE_CB_EVT_REDO_PRE);
+ bmain, &scene->id, (undo_dir == STEP_UNDO) ? BKE_CB_EVT_UNDO_PRE : BKE_CB_EVT_REDO_PRE);
wm->op_undo_depth--;
}
+}
- /* Undo System */
- {
- if (undoname) {
- BKE_undosys_step_undo_with_data(wm->undo_stack, C, step_data_from_name);
- }
- else if (undo_index != -1) {
- BKE_undosys_step_undo_from_index(wm->undo_stack, C, undo_index);
- }
- else {
- if (step == 1) {
- BKE_undosys_step_undo(wm->undo_stack, C);
- }
- else {
- BKE_undosys_step_redo(wm->undo_stack, C);
- }
- }
+/**
+ * Common post management of undo/redo (calling post handlers, adding notifiers etc.).
+ *
+ * \note Also check #undo_history_exec in bottom if you change notifiers.
+ */
+static void ed_undo_step_post(bContext *C,
+ wmWindowManager *wm,
+ const enum eUndoStepDir undo_dir,
+ ReportList *reports)
+{
+ BLI_assert(ELEM(undo_dir, STEP_UNDO, STEP_REDO));
- /* Set special modes for grease pencil */
- if (area && (area->spacetype == SPACE_VIEW3D)) {
- Object *obact = CTX_data_active_object(C);
- if (obact && (obact->type == OB_GPENCIL)) {
- /* set cursor */
- if (ELEM(obact->mode,
- OB_MODE_PAINT_GPENCIL,
- OB_MODE_SCULPT_GPENCIL,
- OB_MODE_WEIGHT_GPENCIL,
- OB_MODE_VERTEX_GPENCIL)) {
- ED_gpencil_toggle_brush_cursor(C, true, NULL);
- }
- else {
- ED_gpencil_toggle_brush_cursor(C, false, NULL);
- }
- /* set workspace mode */
- Base *basact = CTX_data_active_base(C);
- ED_object_base_activate(C, basact);
- }
- }
- }
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
/* App-Handlers (post). */
{
- Main *bmain = CTX_data_main(C);
- scene = CTX_data_scene(C);
wm->op_undo_depth++;
BKE_callback_exec_id(
- bmain, &scene->id, step_for_callback > 0 ? BKE_CB_EVT_UNDO_POST : BKE_CB_EVT_REDO_POST);
+ bmain, &scene->id, (undo_dir == STEP_UNDO) ? BKE_CB_EVT_UNDO_POST : BKE_CB_EVT_REDO_POST);
wm->op_undo_depth--;
}
if (G.debug & G_DEBUG_IO) {
- Main *bmain = CTX_data_main(C);
if (bmain->lock != NULL) {
BKE_report(reports, RPT_INFO, "Checking sanity of current .blend file *AFTER* undo step");
BLO_main_validate_libraries(bmain, reports);
@@ -299,30 +244,123 @@ static int ed_undo_step_impl(
WM_event_add_notifier(C, NC_WM | ND_UNDO, NULL);
WM_toolsystem_refresh_active(C);
-
- Main *bmain = CTX_data_main(C);
WM_toolsystem_refresh_screen_all(bmain);
if (CLOG_CHECK(&LOG, 1)) {
BKE_undosys_print(wm->undo_stack);
}
-
- return OPERATOR_FINISHED;
}
-static int ed_undo_step_direction(bContext *C, int step, ReportList *reports)
+/** Undo or redo one step from current active one.
+ * May undo or redo several steps at once only if the target step is a 'skipped' one.
+ * The target step will be the one immediately before or after the active one. */
+static int ed_undo_step_direction(bContext *C, enum eUndoStepDir step, ReportList *reports)
{
- return ed_undo_step_impl(C, step, NULL, -1, reports);
+ BLI_assert(ELEM(step, STEP_UNDO, STEP_REDO));
+
+ CLOG_INFO(&LOG, 1, "direction=%s", (step == STEP_UNDO) ? "STEP_UNDO" : "STEP_REDO");
+
+ /* TODO(campbell): undo_system: use undo system */
+ /* grease pencil can be can be used in plenty of spaces, so check it first */
+ /* FIXME: This gpencil undo effectively only supports the one step undo/redo, undo based on name
+ * or index is fully not implemented.
+ * FIXME: However, it seems to never be used in current code (`ED_gpencil_session_active` seems
+ * to always return false). */
+ if (ED_gpencil_session_active()) {
+ return ED_undo_gpencil_step(C, step);
+ }
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+
+ ed_undo_step_pre(C, wm, step, reports);
+
+ if (step == STEP_UNDO) {
+ BKE_undosys_step_undo(wm->undo_stack, C);
+ }
+ else {
+ BKE_undosys_step_redo(wm->undo_stack, C);
+ }
+
+ ed_undo_step_post(C, wm, step, reports);
+
+ return OPERATOR_FINISHED;
}
+/** Undo the step matching given name.
+ * May undo several steps at once.
+ * The target step will be the one immediately before given named one. */
static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList *reports)
{
- return ed_undo_step_impl(C, 0, undo_name, -1, reports);
+ BLI_assert(undo_name != NULL);
+
+ /* FIXME: See comments in `ed_undo_step_direction`. */
+ if (ED_gpencil_session_active()) {
+ BLI_assert(!"Not implemented currently.");
+ }
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+ UndoStep *undo_step_from_name = BKE_undosys_step_find_by_name(wm->undo_stack, undo_name);
+ if (undo_step_from_name == NULL) {
+ CLOG_ERROR(&LOG, "Step name='%s' not found in current undo stack", undo_name);
+
+ return OPERATOR_CANCELLED;
+ }
+
+ UndoStep *undo_step_target = undo_step_from_name->prev;
+ if (undo_step_target == NULL) {
+ CLOG_ERROR(&LOG, "Step name='%s' cannot be undone", undo_name);
+
+ return OPERATOR_CANCELLED;
+ }
+
+ const int undo_dir_i = BKE_undosys_step_calc_direction(wm->undo_stack, undo_step_target, NULL);
+ BLI_assert(ELEM(undo_dir_i, -1, 1));
+ const enum eUndoStepDir undo_dir = (undo_dir_i == -1) ? STEP_UNDO : STEP_REDO;
+
+ CLOG_INFO(&LOG,
+ 1,
+ "name='%s', found direction=%s",
+ undo_name,
+ (undo_dir == STEP_UNDO) ? "STEP_UNDO" : "STEP_REDO");
+
+ ed_undo_step_pre(C, wm, undo_dir, reports);
+
+ BKE_undosys_step_load_data_ex(wm->undo_stack, C, undo_step_target, NULL, true);
+
+ ed_undo_step_post(C, wm, undo_dir, reports);
+
+ return OPERATOR_FINISHED;
}
-static int ed_undo_step_by_index(bContext *C, int index, ReportList *reports)
+/** Load the step matching given index in the stack.
+ * May undo or redo several steps at once.
+ * The target step will be the one indicated by the given index. */
+static int ed_undo_step_by_index(bContext *C, const int undo_index, ReportList *reports)
{
- return ed_undo_step_impl(C, 0, NULL, index, reports);
+ BLI_assert(undo_index >= 0);
+
+ /* FIXME: See comments in `ed_undo_step_direction`. */
+ if (ED_gpencil_session_active()) {
+ BLI_assert(!"Not implemented currently.");
+ }
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+ const int active_step_index = BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active);
+ const enum eUndoStepDir undo_dir = (undo_index < active_step_index) ? STEP_UNDO : STEP_REDO;
+
+ CLOG_INFO(&LOG,
+ 1,
+ "index='%d', found direction=%s",
+ undo_index,
+ (undo_dir == STEP_UNDO) ? "STEP_UNDO" : "STEP_REDO");
+
+ ed_undo_step_pre(C, wm, undo_dir, reports);
+
+ BKE_undosys_step_load_from_index(wm->undo_stack, C, undo_index);
+
+ ed_undo_step_post(C, wm, undo_dir, reports);
+
+ return OPERATOR_FINISHED;
}
void ED_undo_grouped_push(bContext *C, const char *str)
@@ -340,11 +378,11 @@ void ED_undo_grouped_push(bContext *C, const char *str)
void ED_undo_pop(bContext *C)
{
- ed_undo_step_direction(C, 1, NULL);
+ ed_undo_step_direction(C, STEP_UNDO, NULL);
}
void ED_undo_redo(bContext *C)
{
- ed_undo_step_direction(C, -1, NULL);
+ ed_undo_step_direction(C, STEP_REDO, NULL);
}
void ED_undo_push_op(bContext *C, wmOperator *op)
@@ -448,7 +486,7 @@ static int ed_undo_exec(bContext *C, wmOperator *op)
{
/* "last operator" should disappear, later we can tie this with undo stack nicer */
WM_operator_stack_clear(CTX_wm_manager(C));
- int ret = ed_undo_step_direction(C, 1, op->reports);
+ int ret = ed_undo_step_direction(C, STEP_UNDO, op->reports);
if (ret & OPERATOR_FINISHED) {
/* Keep button under the cursor active. */
WM_event_add_mousemove(CTX_wm_window(C));
@@ -477,7 +515,7 @@ static int ed_undo_push_exec(bContext *C, wmOperator *op)
static int ed_redo_exec(bContext *C, wmOperator *op)
{
- int ret = ed_undo_step_direction(C, -1, op->reports);
+ int ret = ed_undo_step_direction(C, STEP_REDO, op->reports);
if (ret & OPERATOR_FINISHED) {
/* Keep button under the cursor active. */
WM_event_add_mousemove(CTX_wm_window(C));
diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c
index eea0f29d295..4fd8c180a4b 100644
--- a/source/blender/editors/undo/memfile_undo.c
+++ b/source/blender/editors/undo/memfile_undo.c
@@ -145,19 +145,18 @@ static int memfile_undosys_step_id_reused_cb(LibraryIDLinkCallbackData *cb_data)
static void memfile_undosys_step_decode(struct bContext *C,
struct Main *bmain,
UndoStep *us_p,
- int undo_direction,
+ const eUndoStepDir undo_direction,
bool UNUSED(is_final))
{
- BLI_assert(undo_direction != 0);
+ BLI_assert(undo_direction != STEP_INVALID);
bool use_old_bmain_data = true;
if (USER_EXPERIMENTAL_TEST(&U, use_undo_legacy)) {
use_old_bmain_data = false;
}
- else if (undo_direction > 0) {
- /* Redo case.
- * The only time we should have to force a complete redo is when current step is tagged as a
+ else if (undo_direction == STEP_REDO) {
+ /* The only time we should have to force a complete redo is when current step is tagged as a
* redo barrier.
* If previous step was not a memfile one should not matter here, current data in old bmain
* should still always be valid for unchanged data-blocks. */
@@ -165,9 +164,8 @@ static void memfile_undosys_step_decode(struct bContext *C,
use_old_bmain_data = false;
}
}
- else {
- /* Undo case.
- * Here we do not care whether current step is an undo barrier, since we are coming from
+ else if (undo_direction == STEP_UNDO) {
+ /* Here we do not care whether current step is an undo barrier, since we are coming from
* 'the future' we can still re-use old data. However, if *next* undo step
* (i.e. the one immediately in the future, the one we are coming from)
* is a barrier, then we have to force a complete undo.
@@ -316,8 +314,8 @@ struct MemFile *ED_undosys_stack_memfile_get_active(UndoStack *ustack)
* If the last undo step is a memfile one, find the first #MemFileChunk matching given ID
* (using its session UUID), and tag it as "changed in the future".
*
- * Since non-memfile undos cannot automatically set this flag in the previous step as done with
- * memfile ones, this has to be called manually by relevant undo code.
+ * Since non-memfile undo-steps cannot automatically set this flag in the previous step as done
+ * with memfile ones, this has to be called manually by relevant undo code.
*
* \note Only current known case for this is undoing a switch from Object to Sculpt mode (see
* T82388).
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 0aab3810254..38655b8490e 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -39,7 +39,7 @@ set(SRC
ed_transverts.c
ed_util.c
ed_util_imbuf.c
- ed_util_ops.c
+ ed_util_ops.cc
gizmo_utils.c
numinput.c
select_utils.c
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index 1075f256a09..d0234dee856 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -495,8 +495,8 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
}
if (!tvs->transverts_tot && tvs->transverts) {
- /* prevent memory leak. happens for curves/latticies due to */
- /* difficult condition of adding points to trans data */
+ /* Prevent memory leak. happens for curves/lattices due to
+ * difficult condition of adding points to trans data. */
MEM_freeN(tvs->transverts);
tvs->transverts = NULL;
}
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index c59fbbe1646..695db9ba246 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -183,7 +183,7 @@ void ED_editors_exit(Main *bmain, bool do_undo_system)
return;
}
- /* frees all editmode undos */
+ /* Frees all edit-mode undo-steps. */
if (do_undo_system && G_MAIN->wm.first) {
wmWindowManager *wm = G_MAIN->wm.first;
/* normally we don't check for NULL undo stack,
diff --git a/source/blender/editors/util/ed_util_ops.c b/source/blender/editors/util/ed_util_ops.cc
index bb531b11b12..cb7ff9f3a63 100644
--- a/source/blender/editors/util/ed_util_ops.c
+++ b/source/blender/editors/util/ed_util_ops.cc
@@ -22,6 +22,9 @@
#include <string.h>
+#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
+
#include "BLI_fileops.h"
#include "BLI_utildefines.h"
@@ -33,9 +36,6 @@
#include "BLT_translation.h"
-#include "DNA_space_types.h"
-#include "DNA_windowmanager_types.h"
-
#include "ED_render.h"
#include "ED_undo.h"
#include "ED_util.h"
@@ -56,7 +56,7 @@ static bool lib_id_preview_editing_poll(bContext *C)
const PointerRNA idptr = CTX_data_pointer_get(C, "id");
BLI_assert(!idptr.data || RNA_struct_is_ID(idptr.type));
- const ID *id = idptr.data;
+ const ID *id = (ID *)idptr.data;
if (!id) {
return false;
}
@@ -88,11 +88,11 @@ static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op)
}
PointerRNA idptr = CTX_data_pointer_get(C, "id");
- ID *id = idptr.data;
+ ID *id = (ID *)idptr.data;
BKE_previewimg_id_custom_set(id, path);
- WM_event_add_notifier(C, NC_ASSET, NULL);
+ WM_event_add_notifier(C, NC_ASSET, nullptr);
return OPERATOR_FINISHED;
}
@@ -123,7 +123,7 @@ static void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot)
static int lib_id_generate_preview_exec(bContext *C, wmOperator *UNUSED(op))
{
PointerRNA idptr = CTX_data_pointer_get(C, "id");
- ID *id = idptr.data;
+ ID *id = (ID *)idptr.data;
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
@@ -131,9 +131,9 @@ static int lib_id_generate_preview_exec(bContext *C, wmOperator *UNUSED(op))
if (preview) {
BKE_previewimg_clear(preview);
}
- UI_icon_render_id(C, NULL, id, ICON_SIZE_PREVIEW, true);
+ UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
- WM_event_add_notifier(C, NC_ASSET, NULL);
+ WM_event_add_notifier(C, NC_ASSET, nullptr);
return OPERATOR_FINISHED;
}
@@ -169,15 +169,15 @@ static int lib_id_fake_user_toggle_exec(bContext *C, wmOperator *op)
idptr = RNA_property_pointer_get(&pprop.ptr, pprop.prop);
}
- if ((pprop.prop == NULL) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) {
+ if ((pprop.prop == nullptr) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) {
BKE_report(
op->reports, RPT_ERROR, "Incorrect context for running data-block fake user toggling");
return OPERATOR_CANCELLED;
}
- ID *id = idptr.data;
+ ID *id = (ID *)idptr.data;
- if ((id->lib != NULL) || (ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) {
+ if ((id->lib != nullptr) || (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;
}
@@ -217,14 +217,14 @@ static int lib_id_unlink_exec(bContext *C, wmOperator *op)
idptr = RNA_property_pointer_get(&pprop.ptr, pprop.prop);
}
- if ((pprop.prop == NULL) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) {
+ if ((pprop.prop == nullptr) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) {
BKE_report(
op->reports, RPT_ERROR, "Incorrect context for running data-block fake user toggling");
return OPERATOR_CANCELLED;
}
memset(&idptr, 0, sizeof(idptr));
- RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr, NULL);
+ RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr, nullptr);
RNA_property_update(C, &pprop.ptr, pprop.prop);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index ba22bcca0e1..91ec8546225 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -508,7 +508,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
#endif
case EVT_CKEY:
if (event->ctrl) {
- /* Copy current str to the copypaste buffer. */
+ /* Copy current `str` to the copy/paste buffer. */
WM_clipboard_text_set(n->str, 0);
updated = true;
}
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index ed9e5053f10..e94aaa49839 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -978,7 +978,7 @@ static int p_connect_pairs(PHandle *handle, PBool topology_from_uvs)
PChart *chart = handle->construction_chart;
int ncharts = 0;
- /* connect pairs, count edges, set vertex-edge pointer to a pairless edge */
+ /* Connect pairs, count edges, set vertex-edge pointer to a pair-less edge. */
for (first = chart->faces; first; first = first->nextlink) {
if (first->flag & PFACE_CONNECTED) {
continue;
@@ -1974,7 +1974,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
b[1] = p_vec_angle(v2->co, v1->co, keepv->co);
b[2] = M_PI - b[0] - b[1];
- /* abf criterion 1: avoid sharp and obtuse angles */
+ /* ABF criterion 1: avoid sharp and obtuse angles. */
minangle = 15.0f * M_PI / 180.0f;
maxangle = M_PI - minangle;
@@ -1991,7 +1991,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
} while (e && (e != oldv->edge));
if (p_vert_interior(oldv)) {
- /* hlscm criterion: angular defect smaller than threshold */
+ /* HLSCM criterion: angular defect smaller than threshold. */
if (fabsf(angulardefect) > (float)(M_PI * 30.0 / 180.0)) {
return P_FALSE;
}
@@ -2000,12 +2000,12 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
PVert *v1 = p_boundary_edge_next(oldv->edge)->vert;
PVert *v2 = p_boundary_edge_prev(oldv->edge)->vert;
- /* abf++ criterion 2: avoid collapsing verts inwards */
+ /* ABF++ criterion 2: avoid collapsing verts inwards. */
if (p_vert_interior(keepv)) {
return P_FALSE;
}
- /* don't collapse significant boundary changes */
+ /* Don't collapse significant boundary changes. */
angle = p_vec_angle(v1->co, oldv->co, v2->co);
if (angle < (M_PI * 160.0 / 180.0)) {
return P_FALSE;
@@ -3837,7 +3837,7 @@ static void p_chart_rotate_fit_aabb(PChart *chart)
/* Area Smoothing */
-/* 2d bsp tree for inverse mapping - that's a bit silly */
+/* 2d BSP tree for inverse mapping - that's a bit silly. */
typedef struct SmoothTriangle {
float co1[2], co2[2], co3[2];
@@ -4288,7 +4288,7 @@ static void p_smooth(PChart *chart)
MEM_freeN(hedges);
MEM_freeN(vedges);
- /* create bsp */
+ /* Create BSP. */
t = triangles = MEM_mallocN(sizeof(SmoothTriangle) * esize * 2, "PSmoothTris");
trip = tri = MEM_mallocN(sizeof(SmoothTriangle *) * esize * 2, "PSmoothTriP");
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 7b27bb570cc..8ebf000baaa 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -129,8 +129,10 @@ typedef struct UvEdge {
/** general use flag
* (Used to check if edge is boundary here, and propagates to adjacency elements) */
uchar flag;
- /** element that guarantees element->face
- * has the edge on element->tfindex and element->tfindex+1 is the second uv */
+ /**
+ * Element that guarantees `element.l` has the edge on
+ * `element.loop_of_poly_index` and `element->loop_of_poly_index + 1` is the second UV.
+ */
UvElement *element;
/** next uv edge with the same exact vertices as this one.
* Calculated at startup to save time */
@@ -224,13 +226,13 @@ enum StitchModes {
STITCH_EDGE,
};
-/* UvElement identification. */
+/** #UvElement identification. */
typedef struct UvElementID {
int faceIndex;
int elementIndex;
} UvElementID;
-/* StitchState initializition. */
+/** #StitchState initialization. */
typedef struct StitchStateInit {
int uv_selected_count;
UvElementID *to_select;
@@ -2050,7 +2052,7 @@ static StitchState *stitch_init(bContext *C,
BLI_ghash_free(edge_hash, NULL, NULL);
- /* refill an edge hash to create edge connnectivity data */
+ /* Refill an edge hash to create edge connectivity data. */
state->edge_hash = edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
for (i = 0; i < total_edges; i++) {
BLI_ghash_insert(edge_hash, edges + i, edges + i);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index be54df1ce9e..fc5f41e8ed5 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -1336,9 +1336,9 @@ static void uv_map_rotation_matrix_ex(float result[4][4],
zero_m4(rotup);
zero_m4(rotside);
- /* compensate front/side.. against opengl x,y,z world definition */
- /* this is "kanonen gegen spatzen", a few plus minus 1 will do here */
- /* i wanted to keep the reason here, so we're rotating*/
+ /* Compensate front/side.. against opengl x,y,z world definition.
+ * This is "a sledgehammer to crack a nut" (overkill), a few plus minus 1 will do here.
+ * I wanted to keep the reason here, so we're rotating. */
sideangle = (float)M_PI * (sideangledeg + 180.0f) / 180.0f;
rotside[0][0] = cosf(sideangle);
rotside[0][1] = -sinf(sideangle);
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index ddd11729e67..9c675c93a2e 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -580,7 +580,7 @@ void Controller::ComputeViewMap()
vmBuilder.setRenderMonitor(_pRenderMonitor);
#if 0
- // Builds a tesselated form of the silhouette for display purpose:
+ // Builds a tessellated form of the silhouette for display purpose:
//---------------------------------------------------------------
ViewMapTesselator3D sTesselator3d;
ViewMapTesselator2D sTesselator2d;
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index 930da3ef471..a16479873e7 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -56,11 +56,6 @@ NodeGroup *BlenderFileLoader::Load()
// creation of the scene root node
_Scene = new NodeGroup;
- _viewplane_left = _re->viewplane.xmin;
- _viewplane_right = _re->viewplane.xmax;
- _viewplane_bottom = _re->viewplane.ymin;
- _viewplane_top = _re->viewplane.ymax;
-
if (_re->clip_start < 0.0f) {
// Adjust clipping start/end and set up a Z offset when the viewport preview
// is used with the orthographic view. In this case, _re->clip_start is negative,
@@ -76,14 +71,6 @@ NodeGroup *BlenderFileLoader::Load()
_z_offset = 0.0f;
}
-#if 0
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Frustum: l " << _viewplane_left << " r " << _viewplane_right << " b "
- << _viewplane_bottom << " t " << _viewplane_top << " n " << _z_near << " f " << _z_far
- << endl;
- }
-#endif
-
int id = 0;
const eEvaluationMode eval_mode = DEG_get_mode(_depsgraph);
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
index 50834db3c5c..1be2fc3bc99 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
@@ -152,10 +152,6 @@ class BlenderFileLoader {
real _minEdgeSize;
#endif
bool _smooth; /* if true, face smoothness is taken into account */
- float _viewplane_left;
- float _viewplane_right;
- float _viewplane_bottom;
- float _viewplane_top;
float _z_near, _z_far;
float _z_offset;
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
index 51727fd2288..d3a3d8bc76e 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
@@ -435,12 +435,12 @@ bool overlapTriangleBox(Vec3r &boxcenter, Vec3r &boxhalfsize, Vec3r triverts[3])
// Tomas Möller
// Prosolvia Clarus AB
// Sweden
-// tompa@clarus.se
+// <tompa@clarus.se>
//
// Ben Trumbore
// Cornell University
// Ithaca, New York
-// wbt@graphics.cornell.edu
+// <wbt@graphics.cornell.edu>
bool intersectRayTriangle(const Vec3r &orig,
const Vec3r &dir,
const Vec3r &v0,
diff --git a/source/blender/freestyle/intern/geometry/matrix_util.cpp b/source/blender/freestyle/intern/geometry/matrix_util.cpp
index 5b5d9582e8f..95a24d85677 100644
--- a/source/blender/freestyle/intern/geometry/matrix_util.cpp
+++ b/source/blender/freestyle/intern/geometry/matrix_util.cpp
@@ -17,7 +17,7 @@
* GXML/Graphite: Geometry and Graphics Programming Library + Utilities
* Copyright (C) 2000 Bruno Levy
* Contact: Bruno Levy
- * levy@loria.fr
+ * <levy@loria.fr>
* ISA Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
diff --git a/source/blender/freestyle/intern/geometry/matrix_util.h b/source/blender/freestyle/intern/geometry/matrix_util.h
index 8a20cb31300..8c2eb799d13 100644
--- a/source/blender/freestyle/intern/geometry/matrix_util.h
+++ b/source/blender/freestyle/intern/geometry/matrix_util.h
@@ -17,7 +17,7 @@
* GXML/Graphite: Geometry and Graphics Programming Library + Utilities
* Copyright (C) 2000 Bruno Levy
* Contact: Bruno Levy
- * levy@loria.fr
+ * <levy@loria.fr>
* ISA Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
diff --git a/source/blender/freestyle/intern/geometry/normal_cycle.cpp b/source/blender/freestyle/intern/geometry/normal_cycle.cpp
index 01d52646eb0..2310525a1e1 100644
--- a/source/blender/freestyle/intern/geometry/normal_cycle.cpp
+++ b/source/blender/freestyle/intern/geometry/normal_cycle.cpp
@@ -17,7 +17,7 @@
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
* Copyright (C) 2000 Bruno Levy
* Contact: Bruno Levy
- * levy@loria.fr
+ * <levy@loria.fr>
* ISA Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
diff --git a/source/blender/freestyle/intern/geometry/normal_cycle.h b/source/blender/freestyle/intern/geometry/normal_cycle.h
index 6ac9779e7c2..5adef773be1 100644
--- a/source/blender/freestyle/intern/geometry/normal_cycle.h
+++ b/source/blender/freestyle/intern/geometry/normal_cycle.h
@@ -17,7 +17,7 @@
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
* Copyright (C) 2000 Bruno Levy
* Contact: Bruno Levy
- * levy@loria.fr
+ * <levy@loria.fr>
* ISA Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
diff --git a/source/blender/freestyle/intern/python/BPy_BBox.cpp b/source/blender/freestyle/intern/python/BPy_BBox.cpp
index d66a74bc83f..39dd55f0cc1 100644
--- a/source/blender/freestyle/intern/python/BPy_BBox.cpp
+++ b/source/blender/freestyle/intern/python/BPy_BBox.cpp
@@ -24,6 +24,9 @@
extern "C" {
#endif
+using namespace Freestyle;
+using namespace Freestyle::Geometry;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_BBox.h b/source/blender/freestyle/intern/python/BPy_BBox.h
index a284deed10c..889dbc62a41 100644
--- a/source/blender/freestyle/intern/python/BPy_BBox.h
+++ b/source/blender/freestyle/intern/python/BPy_BBox.h
@@ -27,9 +27,6 @@ extern "C" {
#include "../geometry/BBox.h"
#include "../geometry/Geom.h"
-using namespace Freestyle;
-using namespace Freestyle::Geometry;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -42,7 +39,7 @@ extern PyTypeObject BBox_Type;
/*---------------------------Python BPy_BBox structure definition----------*/
typedef struct {
- PyObject_HEAD BBox<Vec3r> *bb;
+ PyObject_HEAD Freestyle::BBox<Freestyle::Geometry::Vec3r> *bb;
} BPy_BBox;
/*---------------------------Python BPy_BBox visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
index 2359d79f7d0..d12804761f0 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
index cdf81f3e4fc..a368d4cd47e 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../stroke/Predicates0D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +39,7 @@ extern PyTypeObject BinaryPredicate0D_Type;
/*---------------------------Python BPy_BinaryPredicate0D structure definition----------*/
typedef struct {
- PyObject_HEAD BinaryPredicate0D *bp0D;
+ PyObject_HEAD Freestyle::BinaryPredicate0D *bp0D;
} BPy_BinaryPredicate0D;
/*---------------------------Python BPy_BinaryPredicate0D visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
index 7d554e0abe1..969041702b5 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
@@ -33,6 +33,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
index b761f6f6ace..b34fad9e213 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../stroke/Predicates1D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +39,7 @@ extern PyTypeObject BinaryPredicate1D_Type;
/*---------------------------Python BPy_BinaryPredicate1D structure definition----------*/
typedef struct {
- PyObject_HEAD BinaryPredicate1D *bp1D;
+ PyObject_HEAD Freestyle::BinaryPredicate1D *bp1D;
} BPy_BinaryPredicate1D;
/*---------------------------Python BPy_BinaryPredicate1D visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp
index f1d7a242a93..99ba3090137 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp
@@ -61,6 +61,9 @@
extern "C" {
#endif
+using namespace Freestyle;
+using namespace Freestyle::Geometry;
+
///////////////////////////////////////////////////////////////////////////////////////////
//==============================
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.h b/source/blender/freestyle/intern/python/BPy_Convert.h
index 5a1c11ec086..e0916196808 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.h
+++ b/source/blender/freestyle/intern/python/BPy_Convert.h
@@ -28,9 +28,6 @@ extern "C" {
#include "../geometry/Geom.h"
-using namespace Freestyle;
-using namespace Freestyle::Geometry;
-
// BBox
#include "../geometry/BBox.h"
@@ -94,76 +91,81 @@ extern "C" {
//==============================
PyObject *PyBool_from_bool(bool b);
-PyObject *Vector_from_Vec2f(Vec2f &v);
-PyObject *Vector_from_Vec3f(Vec3f &v);
-PyObject *Vector_from_Vec3r(Vec3r &v);
-
-PyObject *Any_BPy_Interface0D_from_Interface0D(Interface0D &if0D);
-PyObject *Any_BPy_Interface1D_from_Interface1D(Interface1D &if1D);
-PyObject *Any_BPy_FEdge_from_FEdge(FEdge &fe);
-PyObject *Any_BPy_ViewVertex_from_ViewVertex(ViewVertex &vv);
-
-PyObject *BPy_BBox_from_BBox(const BBox<Vec3r> &bb);
-PyObject *BPy_CurvePoint_from_CurvePoint(CurvePoint &cp);
-PyObject *BPy_directedViewEdge_from_directedViewEdge(ViewVertex::directedViewEdge &dve);
-PyObject *BPy_FEdge_from_FEdge(FEdge &fe);
-PyObject *BPy_FEdgeSharp_from_FEdgeSharp(FEdgeSharp &fes);
-PyObject *BPy_FEdgeSmooth_from_FEdgeSmooth(FEdgeSmooth &fes);
-PyObject *BPy_Id_from_Id(Id &id);
-PyObject *BPy_Interface0D_from_Interface0D(Interface0D &if0D);
-PyObject *BPy_Interface1D_from_Interface1D(Interface1D &if1D);
-PyObject *BPy_IntegrationType_from_IntegrationType(IntegrationType i);
-PyObject *BPy_FrsMaterial_from_FrsMaterial(const FrsMaterial &m);
+PyObject *Vector_from_Vec2f(Freestyle::Geometry::Vec2f &v);
+PyObject *Vector_from_Vec3f(Freestyle::Geometry::Vec3f &v);
+PyObject *Vector_from_Vec3r(Freestyle::Geometry::Vec3r &v);
+
+PyObject *Any_BPy_Interface0D_from_Interface0D(Freestyle::Interface0D &if0D);
+PyObject *Any_BPy_Interface1D_from_Interface1D(Freestyle::Interface1D &if1D);
+PyObject *Any_BPy_FEdge_from_FEdge(Freestyle::FEdge &fe);
+PyObject *Any_BPy_ViewVertex_from_ViewVertex(Freestyle::ViewVertex &vv);
+
+PyObject *BPy_BBox_from_BBox(const Freestyle::BBox<Freestyle::Geometry::Vec3r> &bb);
+PyObject *BPy_CurvePoint_from_CurvePoint(Freestyle::CurvePoint &cp);
+PyObject *BPy_directedViewEdge_from_directedViewEdge(Freestyle::ViewVertex::directedViewEdge &dve);
+PyObject *BPy_FEdge_from_FEdge(Freestyle::FEdge &fe);
+PyObject *BPy_FEdgeSharp_from_FEdgeSharp(Freestyle::FEdgeSharp &fes);
+PyObject *BPy_FEdgeSmooth_from_FEdgeSmooth(Freestyle::FEdgeSmooth &fes);
+PyObject *BPy_Id_from_Id(Freestyle::Id &id);
+PyObject *BPy_Interface0D_from_Interface0D(Freestyle::Interface0D &if0D);
+PyObject *BPy_Interface1D_from_Interface1D(Freestyle::Interface1D &if1D);
+PyObject *BPy_IntegrationType_from_IntegrationType(Freestyle::IntegrationType i);
+PyObject *BPy_FrsMaterial_from_FrsMaterial(const Freestyle::FrsMaterial &m);
PyObject *BPy_Nature_from_Nature(unsigned short n);
-PyObject *BPy_MediumType_from_MediumType(Stroke::MediumType n);
-PyObject *BPy_SShape_from_SShape(SShape &ss);
-PyObject *BPy_Stroke_from_Stroke(Stroke &s);
-PyObject *BPy_StrokeAttribute_from_StrokeAttribute(StrokeAttribute &sa);
-PyObject *BPy_StrokeVertex_from_StrokeVertex(StrokeVertex &sv);
-PyObject *BPy_SVertex_from_SVertex(SVertex &sv);
-PyObject *BPy_ViewVertex_from_ViewVertex(ViewVertex &vv);
-PyObject *BPy_NonTVertex_from_NonTVertex(NonTVertex &ntv);
-PyObject *BPy_TVertex_from_TVertex(TVertex &tv);
-PyObject *BPy_ViewEdge_from_ViewEdge(ViewEdge &ve);
-PyObject *BPy_Chain_from_Chain(Chain &c);
-PyObject *BPy_ViewShape_from_ViewShape(ViewShape &vs);
-
-PyObject *BPy_AdjacencyIterator_from_AdjacencyIterator(AdjacencyIterator &a_it);
-PyObject *BPy_Interface0DIterator_from_Interface0DIterator(Interface0DIterator &if0D_it,
+PyObject *BPy_MediumType_from_MediumType(Freestyle::Stroke::MediumType n);
+PyObject *BPy_SShape_from_SShape(Freestyle::SShape &ss);
+PyObject *BPy_Stroke_from_Stroke(Freestyle::Stroke &s);
+PyObject *BPy_StrokeAttribute_from_StrokeAttribute(Freestyle::StrokeAttribute &sa);
+PyObject *BPy_StrokeVertex_from_StrokeVertex(Freestyle::StrokeVertex &sv);
+PyObject *BPy_SVertex_from_SVertex(Freestyle::SVertex &sv);
+PyObject *BPy_ViewVertex_from_ViewVertex(Freestyle::ViewVertex &vv);
+PyObject *BPy_NonTVertex_from_NonTVertex(Freestyle::NonTVertex &ntv);
+PyObject *BPy_TVertex_from_TVertex(Freestyle::TVertex &tv);
+PyObject *BPy_ViewEdge_from_ViewEdge(Freestyle::ViewEdge &ve);
+PyObject *BPy_Chain_from_Chain(Freestyle::Chain &c);
+PyObject *BPy_ViewShape_from_ViewShape(Freestyle::ViewShape &vs);
+
+PyObject *BPy_AdjacencyIterator_from_AdjacencyIterator(Freestyle::AdjacencyIterator &a_it);
+PyObject *BPy_Interface0DIterator_from_Interface0DIterator(Freestyle::Interface0DIterator &if0D_it,
bool reversed);
-PyObject *BPy_CurvePointIterator_from_CurvePointIterator(CurveInternal::CurvePointIterator &cp_it);
+PyObject *BPy_CurvePointIterator_from_CurvePointIterator(
+ Freestyle::CurveInternal::CurvePointIterator &cp_it);
PyObject *BPy_StrokeVertexIterator_from_StrokeVertexIterator(
- StrokeInternal::StrokeVertexIterator &sv_it, bool reversed);
-PyObject *BPy_SVertexIterator_from_SVertexIterator(ViewEdgeInternal::SVertexIterator &sv_it);
+ Freestyle::StrokeInternal::StrokeVertexIterator &sv_it, bool reversed);
+PyObject *BPy_SVertexIterator_from_SVertexIterator(
+ Freestyle::ViewEdgeInternal::SVertexIterator &sv_it);
PyObject *BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator(
- ViewVertexInternal::orientedViewEdgeIterator &ove_it, bool reversed);
-PyObject *BPy_ViewEdgeIterator_from_ViewEdgeIterator(ViewEdgeInternal::ViewEdgeIterator &ve_it);
-PyObject *BPy_ChainingIterator_from_ChainingIterator(ChainingIterator &c_it);
-PyObject *BPy_ChainPredicateIterator_from_ChainPredicateIterator(ChainPredicateIterator &cp_it);
-PyObject *BPy_ChainSilhouetteIterator_from_ChainSilhouetteIterator(ChainSilhouetteIterator &cs_it);
+ Freestyle::ViewVertexInternal::orientedViewEdgeIterator &ove_it, bool reversed);
+PyObject *BPy_ViewEdgeIterator_from_ViewEdgeIterator(
+ Freestyle::ViewEdgeInternal::ViewEdgeIterator &ve_it);
+PyObject *BPy_ChainingIterator_from_ChainingIterator(Freestyle::ChainingIterator &c_it);
+PyObject *BPy_ChainPredicateIterator_from_ChainPredicateIterator(
+ Freestyle::ChainPredicateIterator &cp_it);
+PyObject *BPy_ChainSilhouetteIterator_from_ChainSilhouetteIterator(
+ Freestyle::ChainSilhouetteIterator &cs_it);
//==============================
// Python => C++
//==============================
bool bool_from_PyBool(PyObject *b);
-IntegrationType IntegrationType_from_BPy_IntegrationType(PyObject *obj);
-Stroke::MediumType MediumType_from_BPy_MediumType(PyObject *obj);
-Nature::EdgeNature EdgeNature_from_BPy_Nature(PyObject *obj);
-bool Vec2f_ptr_from_PyObject(PyObject *obj, Vec2f &vec);
-bool Vec3f_ptr_from_PyObject(PyObject *obj, Vec3f &vec);
-bool Vec3r_ptr_from_PyObject(PyObject *obj, Vec3r &vec);
-bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f &vec);
-bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f &vec);
-bool Vec3r_ptr_from_Vector(PyObject *obj, Vec3r &vec);
-bool Vec3f_ptr_from_Color(PyObject *obj, Vec3f &vec);
-bool Vec3r_ptr_from_Color(PyObject *obj, Vec3r &vec);
-bool Vec2f_ptr_from_PyList(PyObject *obj, Vec2f &vec);
-bool Vec3f_ptr_from_PyList(PyObject *obj, Vec3f &vec);
-bool Vec3r_ptr_from_PyList(PyObject *obj, Vec3r &vec);
-bool Vec2f_ptr_from_PyTuple(PyObject *obj, Vec2f &vec);
-bool Vec3f_ptr_from_PyTuple(PyObject *obj, Vec3f &vec);
-bool Vec3r_ptr_from_PyTuple(PyObject *obj, Vec3r &vec);
+Freestyle::IntegrationType IntegrationType_from_BPy_IntegrationType(PyObject *obj);
+Freestyle::Stroke::MediumType MediumType_from_BPy_MediumType(PyObject *obj);
+Freestyle::Nature::EdgeNature EdgeNature_from_BPy_Nature(PyObject *obj);
+bool Vec2f_ptr_from_PyObject(PyObject *obj, Freestyle::Geometry::Vec2f &vec);
+bool Vec3f_ptr_from_PyObject(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
+bool Vec3r_ptr_from_PyObject(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
+bool Vec2f_ptr_from_Vector(PyObject *obj, Freestyle::Geometry::Vec2f &vec);
+bool Vec3f_ptr_from_Vector(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
+bool Vec3r_ptr_from_Vector(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
+bool Vec3f_ptr_from_Color(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
+bool Vec3r_ptr_from_Color(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
+bool Vec2f_ptr_from_PyList(PyObject *obj, Freestyle::Geometry::Vec2f &vec);
+bool Vec3f_ptr_from_PyList(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
+bool Vec3r_ptr_from_PyList(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
+bool Vec2f_ptr_from_PyTuple(PyObject *obj, Freestyle::Geometry::Vec2f &vec);
+bool Vec3f_ptr_from_PyTuple(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
+bool Vec3r_ptr_from_PyTuple(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
bool float_array_from_PyObject(PyObject *obj, float *v, int n);
diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
index 2aa08ec3ab5..e3e6ba5ab83 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
+++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
@@ -28,6 +28,8 @@ extern "C" {
#include "BLI_hash_mm2a.h"
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.h b/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
index 13a116d7ef2..084fcef9a62 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
+++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../scene_graph/FrsMaterial.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +39,7 @@ extern PyTypeObject FrsMaterial_Type;
/*---------------------------Python BPy_FrsMaterial structure definition----------*/
typedef struct {
- PyObject_HEAD FrsMaterial *m;
+ PyObject_HEAD Freestyle::FrsMaterial *m;
} BPy_FrsMaterial;
/*---------------------------Python BPy_FrsMaterial visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp b/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp
index 943a9ca0e64..73e2abc8688 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp
+++ b/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_FrsNoise.h b/source/blender/freestyle/intern/python/BPy_FrsNoise.h
index 09bcc82ae94..0f8f2d3242c 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsNoise.h
+++ b/source/blender/freestyle/intern/python/BPy_FrsNoise.h
@@ -27,8 +27,6 @@ extern "C" {
#include "../geometry/Noise.h"
#include "../system/PseudoNoise.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,8 +39,8 @@ extern PyTypeObject FrsNoise_Type;
/*---------------------------Python BPy_FrsNoise structure definition----------*/
typedef struct {
- PyObject_HEAD Noise *n;
- PseudoNoise *pn;
+ PyObject_HEAD Freestyle::Noise *n;
+ Freestyle::PseudoNoise *pn;
} BPy_FrsNoise;
/*---------------------------Python BPy_FrsNoise visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_Id.cpp b/source/blender/freestyle/intern/python/BPy_Id.cpp
index 323e76fe249..5f9824db773 100644
--- a/source/blender/freestyle/intern/python/BPy_Id.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Id.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_Id.h b/source/blender/freestyle/intern/python/BPy_Id.h
index f5952297c66..51a70a391b1 100644
--- a/source/blender/freestyle/intern/python/BPy_Id.h
+++ b/source/blender/freestyle/intern/python/BPy_Id.h
@@ -26,12 +26,8 @@ extern "C" {
#include <iostream>
-using namespace std;
-
#include "../system/Id.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -44,7 +40,7 @@ extern PyTypeObject Id_Type;
/*---------------------------Python BPy_Id structure definition----------*/
typedef struct {
- PyObject_HEAD Id *id;
+ PyObject_HEAD Freestyle::Id *id;
} BPy_Id;
/*---------------------------Python BPy_Id visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
index 25f3c54ea7d..15f3f936b14 100644
--- a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
+++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------ MODULE FUNCTIONS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.h b/source/blender/freestyle/intern/python/BPy_IntegrationType.h
index be815c6c95a..9176a504b24 100644
--- a/source/blender/freestyle/intern/python/BPy_IntegrationType.h
+++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../view_map/Interface1D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/source/blender/freestyle/intern/python/BPy_Interface0D.cpp b/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
index 3d0c57d5509..a1456a9491f 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
@@ -34,6 +34,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_Interface0D.h b/source/blender/freestyle/intern/python/BPy_Interface0D.h
index 7e41a8888e1..9734378f446 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface0D.h
+++ b/source/blender/freestyle/intern/python/BPy_Interface0D.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../view_map/Interface0D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +39,7 @@ extern PyTypeObject Interface0D_Type;
/*---------------------------Python BPy_Interface0D structure definition----------*/
typedef struct {
- PyObject_HEAD Interface0D *if0D;
+ PyObject_HEAD Freestyle::Interface0D *if0D;
bool borrowed; /* true if *if0D is a borrowed object */
} BPy_Interface0D;
diff --git a/source/blender/freestyle/intern/python/BPy_Interface1D.cpp b/source/blender/freestyle/intern/python/BPy_Interface1D.cpp
index 8a4a6eb61db..2fe56eb952d 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Interface1D.cpp
@@ -35,6 +35,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_Interface1D.h b/source/blender/freestyle/intern/python/BPy_Interface1D.h
index 20a4af0b4d0..4ed562c24f7 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface1D.h
+++ b/source/blender/freestyle/intern/python/BPy_Interface1D.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../view_map/Interface1D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +39,7 @@ extern PyTypeObject Interface1D_Type;
/*---------------------------Python BPy_Interface1D structure definition----------*/
typedef struct {
- PyObject_HEAD Interface1D *if1D;
+ PyObject_HEAD Freestyle::Interface1D *if1D;
bool borrowed; /* true if *if1D is a borrowed object */
} BPy_Interface1D;
diff --git a/source/blender/freestyle/intern/python/BPy_Iterator.cpp b/source/blender/freestyle/intern/python/BPy_Iterator.cpp
index bee30aa9e8c..5346c4a8dc0 100644
--- a/source/blender/freestyle/intern/python/BPy_Iterator.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Iterator.cpp
@@ -36,6 +36,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_Iterator.h b/source/blender/freestyle/intern/python/BPy_Iterator.h
index 5d1e8422976..7094384140f 100644
--- a/source/blender/freestyle/intern/python/BPy_Iterator.h
+++ b/source/blender/freestyle/intern/python/BPy_Iterator.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../system/Iterator.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -40,7 +38,7 @@ extern PyTypeObject Iterator_Type;
/*---------------------------Python BPy_Iterator structure definition----------*/
typedef struct {
- PyObject_HEAD Iterator *it;
+ PyObject_HEAD Freestyle::Iterator *it;
} BPy_Iterator;
/*---------------------------Python BPy_Iterator visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.cpp b/source/blender/freestyle/intern/python/BPy_MediumType.cpp
index 547f46839b8..35f9dc17070 100644
--- a/source/blender/freestyle/intern/python/BPy_MediumType.cpp
+++ b/source/blender/freestyle/intern/python/BPy_MediumType.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*-----------------------BPy_MediumType type definition ------------------------------*/
diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.h b/source/blender/freestyle/intern/python/BPy_MediumType.h
index 854f826291e..e34edc45f42 100644
--- a/source/blender/freestyle/intern/python/BPy_MediumType.h
+++ b/source/blender/freestyle/intern/python/BPy_MediumType.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../stroke/Stroke.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/source/blender/freestyle/intern/python/BPy_Nature.cpp b/source/blender/freestyle/intern/python/BPy_Nature.cpp
index b0a620803d1..304364b60eb 100644
--- a/source/blender/freestyle/intern/python/BPy_Nature.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Nature.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
static PyObject *BPy_Nature_and(PyObject *a, PyObject *b);
diff --git a/source/blender/freestyle/intern/python/BPy_Nature.h b/source/blender/freestyle/intern/python/BPy_Nature.h
index 48d15c8e796..a105db22b2a 100644
--- a/source/blender/freestyle/intern/python/BPy_Nature.h
+++ b/source/blender/freestyle/intern/python/BPy_Nature.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../winged_edge/Nature.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp
index 5fd02e4a9dd..5dbf18c24a7 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp
@@ -36,6 +36,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
@@ -260,8 +262,8 @@ PyDoc_STRVAR(Operators_sequential_split_doc,
"\n"
" .. tip::\n"
"\n"
- " By specifiying a starting and stopping predicate allows\n"
- " the chains to overlapp rather than chains partitioning.\n"
+ " By specifying a starting and stopping predicate allows\n"
+ " the chains to overlap rather than chains partitioning.\n"
"\n"
" :arg starting_pred: The predicate on a point that expresses the\n"
" starting condition. Each time this condition is verified, a new chain begins\n"
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.h b/source/blender/freestyle/intern/python/BPy_Operators.h
index 3b060d63f3c..9ed6bc2305d 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.h
+++ b/source/blender/freestyle/intern/python/BPy_Operators.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../stroke/Operators.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/source/blender/freestyle/intern/python/BPy_SShape.cpp b/source/blender/freestyle/intern/python/BPy_SShape.cpp
index ed83e76559f..bb1b07a8c4c 100644
--- a/source/blender/freestyle/intern/python/BPy_SShape.cpp
+++ b/source/blender/freestyle/intern/python/BPy_SShape.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_SShape.h b/source/blender/freestyle/intern/python/BPy_SShape.h
index 9741a10f69e..a6fb090a537 100644
--- a/source/blender/freestyle/intern/python/BPy_SShape.h
+++ b/source/blender/freestyle/intern/python/BPy_SShape.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../view_map/Silhouette.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -40,7 +38,7 @@ extern PyTypeObject SShape_Type;
/*---------------------------Python BPy_SShape structure definition----------*/
typedef struct {
- PyObject_HEAD SShape *ss;
+ PyObject_HEAD Freestyle::SShape *ss;
bool borrowed; /* true if *ss is a borrowed object */
} BPy_SShape;
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
index 8f706f56f7d..c95abae3645 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
index 9068eb4c7a3..9c0a7368dcb 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
+++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../stroke/Stroke.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +39,7 @@ extern PyTypeObject StrokeAttribute_Type;
/*---------------------------Python BPy_StrokeAttribute structure definition----------*/
typedef struct {
- PyObject_HEAD StrokeAttribute *sa;
+ PyObject_HEAD Freestyle::StrokeAttribute *sa;
bool borrowed; /* true if *sa is a borrowed reference */
} BPy_StrokeAttribute;
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
index b55da256c22..01f8ec18022 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
@@ -46,6 +46,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.h b/source/blender/freestyle/intern/python/BPy_StrokeShader.h
index 04fff8e8052..74c5df52312 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeShader.h
+++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.h
@@ -26,12 +26,8 @@ extern "C" {
#include "../system/FreestyleConfig.h"
-using namespace std;
-
#include "../stroke/StrokeShader.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -45,7 +41,7 @@ extern PyTypeObject StrokeShader_Type;
/*---------------------------Python BPy_StrokeShader structure definition----------*/
typedef struct {
- PyObject_HEAD StrokeShader *ss;
+ PyObject_HEAD Freestyle::StrokeShader *ss;
} BPy_StrokeShader;
/*---------------------------Python BPy_StrokeShader visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp
index 78c93ddce31..de426183b6a 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp
@@ -35,6 +35,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
index 1319cabe94a..ef3021faf48 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../view_map/Functions0D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp
index 365850b748c..591f69b23df 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp
@@ -33,6 +33,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
index 331c3b4aaa1..4613d58c2b7 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../view_map/Functions1D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
index e3076d4615f..3c3b0fe82e3 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
index 2460b1f028b..3d45c2fc701 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../stroke/Predicates0D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +39,7 @@ extern PyTypeObject UnaryPredicate0D_Type;
/*---------------------------Python BPy_UnaryPredicate0D structure definition----------*/
typedef struct {
- PyObject_HEAD UnaryPredicate0D *up0D;
+ PyObject_HEAD Freestyle::UnaryPredicate0D *up0D;
} BPy_UnaryPredicate0D;
/*---------------------------Python BPy_UnaryPredicate0D visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
index 4b5269a1434..26087d1a6ef 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
@@ -38,6 +38,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
index 8fad7f94caf..0139ed8af77 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../stroke/Predicates1D.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,7 +39,7 @@ extern PyTypeObject UnaryPredicate1D_Type;
/*---------------------------Python BPy_UnaryPredicate1D structure definition----------*/
typedef struct {
- PyObject_HEAD UnaryPredicate1D *up1D;
+ PyObject_HEAD Freestyle::UnaryPredicate1D *up1D;
} BPy_UnaryPredicate1D;
/*---------------------------Python BPy_UnaryPredicate1D visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_ViewMap.cpp b/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
index 8565a95fc1a..24925edecf9 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_ViewMap.h b/source/blender/freestyle/intern/python/BPy_ViewMap.h
index 59738b6dce9..2222b327dc2 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewMap.h
+++ b/source/blender/freestyle/intern/python/BPy_ViewMap.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../view_map/ViewMap.h"
-using namespace Freestyle;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -40,7 +38,7 @@ extern PyTypeObject ViewMap_Type;
/*---------------------------Python BPy_ViewMap structure definition----------*/
typedef struct {
- PyObject_HEAD ViewMap *vm;
+ PyObject_HEAD Freestyle::ViewMap *vm;
} BPy_ViewMap;
/*---------------------------Python BPy_ViewMap visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
index 6c8551867fd..d6964d4d6ec 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.h b/source/blender/freestyle/intern/python/BPy_ViewShape.h
index bd51fd0d5cb..8401c4378f0 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewShape.h
+++ b/source/blender/freestyle/intern/python/BPy_ViewShape.h
@@ -26,8 +26,6 @@ extern "C" {
#include "../view_map/ViewMap.h"
-using namespace Freestyle;
-
#include "BPy_SShape.h"
#ifdef __cplusplus
@@ -42,7 +40,7 @@ extern PyTypeObject ViewShape_Type;
/*---------------------------Python BPy_ViewShape structure definition----------*/
typedef struct {
- PyObject_HEAD ViewShape *vs;
+ PyObject_HEAD Freestyle::ViewShape *vs;
bool borrowed; /* true if *vs a borrowed object */
BPy_SShape *py_ss;
} BPy_ViewShape;
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
index e284f28cd0b..4299cfae214 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
index 2c84f69dd6e..fb057022290 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
index ab79ae4e209..96e35bd305b 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
index 47c3c6b53aa..eb53cfc5b0e 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
index 9d69b1c902c..9522a8da4f7 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Director.cpp b/source/blender/freestyle/intern/python/Director.cpp
index ff1d63f5f58..4dd3f732be9 100644
--- a/source/blender/freestyle/intern/python/Director.cpp
+++ b/source/blender/freestyle/intern/python/Director.cpp
@@ -56,6 +56,8 @@
#include "UnaryFunction1D/BPy_UnaryFunction1DVec3f.h"
#include "UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h"
+using namespace Freestyle;
+
// BinaryPredicate0D: __call__
int Director_BPy_BinaryPredicate0D___call__(BinaryPredicate0D *bp0D,
Interface0D &i1,
diff --git a/source/blender/freestyle/intern/python/Director.h b/source/blender/freestyle/intern/python/Director.h
index 468150524f1..0894911fe14 100644
--- a/source/blender/freestyle/intern/python/Director.h
+++ b/source/blender/freestyle/intern/python/Director.h
@@ -34,31 +34,34 @@ class Stroke;
class StrokeShader;
} // namespace Freestyle
-using namespace Freestyle;
-
// BinaryPredicate0D: __call__
-int Director_BPy_BinaryPredicate0D___call__(BinaryPredicate0D *bp0D,
- Interface0D &i1,
- Interface0D &i2);
+int Director_BPy_BinaryPredicate0D___call__(Freestyle::BinaryPredicate0D *bp0D,
+ Freestyle::Interface0D &i1,
+ Freestyle::Interface0D &i2);
// BinaryPredicate1D: __call__
-int Director_BPy_BinaryPredicate1D___call__(BinaryPredicate1D *bp1D,
- Interface1D &i1,
- Interface1D &i2);
+int Director_BPy_BinaryPredicate1D___call__(Freestyle::BinaryPredicate1D *bp1D,
+ Freestyle::Interface1D &i1,
+ Freestyle::Interface1D &i2);
// UnaryFunction{0D,1D}: __call__
-int Director_BPy_UnaryFunction0D___call__(void *uf0D, void *py_uf0D, Interface0DIterator &if0D_it);
-int Director_BPy_UnaryFunction1D___call__(void *uf1D, void *py_uf1D, Interface1D &if1D);
+int Director_BPy_UnaryFunction0D___call__(void *uf0D,
+ void *py_uf0D,
+ Freestyle::Interface0DIterator &if0D_it);
+int Director_BPy_UnaryFunction1D___call__(void *uf1D, void *py_uf1D, Freestyle::Interface1D &if1D);
// UnaryPredicate0D: __call__
-int Director_BPy_UnaryPredicate0D___call__(UnaryPredicate0D *up0D, Interface0DIterator &if0D_it);
+int Director_BPy_UnaryPredicate0D___call__(Freestyle::UnaryPredicate0D *up0D,
+ Freestyle::Interface0DIterator &if0D_it);
// UnaryPredicate1D: __call__
-int Director_BPy_UnaryPredicate1D___call__(UnaryPredicate1D *up1D, Interface1D &if1D);
+int Director_BPy_UnaryPredicate1D___call__(Freestyle::UnaryPredicate1D *up1D,
+ Freestyle::Interface1D &if1D);
// StrokeShader: shade
-int Director_BPy_StrokeShader_shade(StrokeShader *ss, Stroke &s);
+int Director_BPy_StrokeShader_shade(Freestyle::StrokeShader *ss, Freestyle::Stroke &s);
// ChainingIterator: init, traverse
-int Director_BPy_ChainingIterator_init(ChainingIterator *c_it);
-int Director_BPy_ChainingIterator_traverse(ChainingIterator *c_it, AdjacencyIterator &a_it);
+int Director_BPy_ChainingIterator_init(Freestyle::ChainingIterator *c_it);
+int Director_BPy_ChainingIterator_traverse(Freestyle::ChainingIterator *c_it,
+ Freestyle::AdjacencyIterator &a_it);
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
index f70f70275df..57639b6161b 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------CurvePoint methods----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
index 6a550085817..0def155d22b 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
@@ -37,7 +37,7 @@ extern PyTypeObject CurvePoint_Type;
/*---------------------------Python BPy_CurvePoint structure definition----------*/
typedef struct {
BPy_Interface0D py_if0D;
- CurvePoint *cp;
+ Freestyle::CurvePoint *cp;
} BPy_CurvePoint;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
index b245ecd81f1..63a9ead910e 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------SVertex methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
index 8d24576a98f..d2fa48d17d8 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
@@ -37,7 +37,7 @@ extern PyTypeObject SVertex_Type;
/*---------------------------Python BPy_SVertex structure definition----------*/
typedef struct {
BPy_Interface0D py_if0D;
- SVertex *sv;
+ Freestyle::SVertex *sv;
} BPy_SVertex;
/*---------------------------Python BPy_SVertex visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp
index 696b3022e85..98fb460c3e4 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------ViewVertex methods----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
index cb9815fb3d4..b5881dcafb5 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
@@ -37,7 +37,7 @@ extern PyTypeObject ViewVertex_Type;
/*---------------------------Python BPy_ViewVertex structure definition----------*/
typedef struct {
BPy_Interface0D py_if0D;
- ViewVertex *vv;
+ Freestyle::ViewVertex *vv;
} BPy_ViewVertex;
///////////////////////////////////////////////////////////////////////////////////////////
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 5e63e190356..da8cd9d2395 100644
--- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
index 44da0ed212a..d635a8541db 100644
--- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
@@ -38,7 +38,7 @@ extern PyTypeObject StrokeVertex_Type;
/*---------------------------Python BPy_StrokeVertex structure definition----------*/
typedef struct {
BPy_CurvePoint py_cp;
- StrokeVertex *sv;
+ Freestyle::StrokeVertex *sv;
} BPy_StrokeVertex;
/*---------------------------Python BPy_StrokeVertex visible prototypes-----------*/
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 ed10f3e0af5..90522ba7f9f 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------NonTVertex methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
index 43f2c2b4a5c..6d84533aa6b 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
@@ -37,7 +37,7 @@ extern PyTypeObject NonTVertex_Type;
/*---------------------------Python BPy_NonTVertex structure definition----------*/
typedef struct {
BPy_ViewVertex py_vv;
- NonTVertex *ntv;
+ Freestyle::NonTVertex *ntv;
} BPy_NonTVertex;
///////////////////////////////////////////////////////////////////////////////////////////
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 596eec7a4e5..5f90f0fa7a9 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------TVertex methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
index 253934bb4e7..009ba24d1e8 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
@@ -37,7 +37,7 @@ extern PyTypeObject TVertex_Type;
/*---------------------------Python BPy_TVertex structure definition----------*/
typedef struct {
BPy_ViewVertex py_vv;
- TVertex *tv;
+ Freestyle::TVertex *tv;
} BPy_TVertex;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
index 0438abfd38c..2d019e2a979 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------FEdge methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
index 25b1bc99860..3c259d77a44 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
@@ -37,7 +37,7 @@ extern PyTypeObject FEdge_Type;
/*---------------------------Python BPy_FEdge structure definition----------*/
typedef struct {
BPy_Interface1D py_if1D;
- FEdge *fe;
+ Freestyle::FEdge *fe;
} BPy_FEdge;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
index d77a8007b1a..6a7d4aef08f 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------CurvePoint methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
index 9bdc3919a38..be3e98edefe 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
@@ -37,7 +37,7 @@ extern PyTypeObject FrsCurve_Type;
/*---------------------------Python BPy_FrsCurve structure definition----------*/
typedef struct {
BPy_Interface1D py_if1D;
- Curve *c;
+ Freestyle::Curve *c;
} BPy_FrsCurve;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
index 90cc3e4f1ab..a5792d4bc5a 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
@@ -31,6 +31,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------Stroke methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
index 33c6aa70f91..eb919b4a376 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
@@ -37,7 +37,7 @@ extern PyTypeObject Stroke_Type;
/*---------------------------Python BPy_Stroke structure definition----------*/
typedef struct {
BPy_Interface1D py_if1D;
- Stroke *s;
+ Freestyle::Stroke *s;
} BPy_Stroke;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp
index c416d860c77..bfd093f694e 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp
@@ -32,6 +32,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------ViewEdge methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
index 519081cedbd..ffcdb46cff6 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
@@ -37,7 +37,7 @@ extern PyTypeObject ViewEdge_Type;
/*---------------------------Python BPy_ViewEdge structure definition----------*/
typedef struct {
BPy_Interface1D py_if1D;
- ViewEdge *ve;
+ Freestyle::ViewEdge *ve;
} BPy_ViewEdge;
///////////////////////////////////////////////////////////////////////////////////////////
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 dcf6c149b7d..bbcbe98df3a 100644
--- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------Chain methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
index 73da253688c..279a9cdc945 100644
--- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
+++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
@@ -37,7 +37,7 @@ extern PyTypeObject Chain_Type;
/*---------------------------Python BPy_Chain structure definition----------*/
typedef struct {
BPy_FrsCurve py_c;
- Chain *c;
+ Freestyle::Chain *c;
} BPy_Chain;
///////////////////////////////////////////////////////////////////////////////////////////
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 454a2bb1c0f..f0aec671953 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------FEdgeSharp methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
index 2b8b09a5990..c3d0298bc5c 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
@@ -37,7 +37,7 @@ extern PyTypeObject FEdgeSharp_Type;
/*---------------------------Python BPy_FEdgeSharp structure definition----------*/
typedef struct {
BPy_FEdge py_fe;
- FEdgeSharp *fes;
+ Freestyle::FEdgeSharp *fes;
} BPy_FEdgeSharp;
/*---------------------------Python BPy_FEdgeSharp visible prototypes-----------*/
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 c0d56ec949c..e6461dd6e8a 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
/*----------------------FEdgeSmooth methods ----------------------------*/
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
index 97497281310..d8ddd6c573f 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
@@ -38,7 +38,7 @@ extern PyTypeObject FEdgeSmooth_Type;
/*---------------------------Python BPy_FEdgeSmooth structure definition----------*/
typedef struct {
BPy_FEdge py_fe;
- FEdgeSmooth *fes;
+ Freestyle::FEdgeSmooth *fes;
} BPy_FEdgeSmooth;
/*---------------------------Python BPy_FEdgeSmooth visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
index 9f5f8d07e26..d548396b229 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
index e5332e0d180..1de73dad015 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject AdjacencyIterator_Type;
/*---------------------------Python BPy_AdjacencyIterator structure definition----------*/
typedef struct {
BPy_Iterator py_it;
- AdjacencyIterator *a_it;
+ Freestyle::AdjacencyIterator *a_it;
bool at_start;
} BPy_AdjacencyIterator;
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
index e4cd1cd073b..fe2fa32b184 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
index ece8018d285..ae6f7307e3c 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject ChainPredicateIterator_Type;
/*---------------------------Python BPy_ChainPredicateIterator structure definition----------*/
typedef struct {
BPy_ChainingIterator py_c_it;
- ChainPredicateIterator *cp_it;
+ Freestyle::ChainPredicateIterator *cp_it;
PyObject *upred;
PyObject *bpred;
} BPy_ChainPredicateIterator;
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
index 9aa8984f4af..ac73b231dd0 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
index f91d0fb2585..7eb5ca8d70c 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject ChainSilhouetteIterator_Type;
/*---------------------------Python BPy_ChainSilhouetteIterator structure definition----------*/
typedef struct {
BPy_ChainingIterator py_c_it;
- ChainSilhouetteIterator *cs_it;
+ Freestyle::ChainSilhouetteIterator *cs_it;
} BPy_ChainSilhouetteIterator;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
index f2441fa9d18..c464d30f92e 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
index e950824764c..54fd6e08f05 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject ChainingIterator_Type;
/*---------------------------Python BPy_ChainingIterator structure definition----------*/
typedef struct {
BPy_ViewEdgeIterator py_ve_it;
- ChainingIterator *c_it;
+ Freestyle::ChainingIterator *c_it;
} BPy_ChainingIterator;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
index ff710e931d4..bd7ed9a48da 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
index db36bf386ec..2de21178e95 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject CurvePointIterator_Type;
/*---------------------------Python BPy_CurvePointIterator structure definition----------*/
typedef struct {
BPy_Iterator py_it;
- CurveInternal::CurvePointIterator *cp_it;
+ Freestyle::CurveInternal::CurvePointIterator *cp_it;
} BPy_CurvePointIterator;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
index d0de53fa424..6afa9d25df7 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
index 663193bedee..82e44218634 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject Interface0DIterator_Type;
/*---------------------------Python BPy_Interface0DIterator structure definition----------*/
typedef struct {
BPy_Iterator py_it;
- Interface0DIterator *if0D_it;
+ Freestyle::Interface0DIterator *if0D_it;
bool reversed;
bool at_start;
} BPy_Interface0DIterator;
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
index c0db79858b7..48452f341a5 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
index a34dc7a63c5..c7b18db8e48 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject SVertexIterator_Type;
/*---------------------------Python BPy_SVertexIterator structure definition----------*/
typedef struct {
BPy_Iterator py_it;
- ViewEdgeInternal::SVertexIterator *sv_it;
+ Freestyle::ViewEdgeInternal::SVertexIterator *sv_it;
} BPy_SVertexIterator;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
index ceb0d2a7546..fdcb4d34c70 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
index 629471a664c..d7ad3d99a54 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject StrokeVertexIterator_Type;
/*---------------------------Python BPy_StrokeVertexIterator structure definition----------*/
typedef struct {
BPy_Iterator py_it;
- StrokeInternal::StrokeVertexIterator *sv_it;
+ Freestyle::StrokeInternal::StrokeVertexIterator *sv_it;
bool reversed;
/* attribute to make next() work correctly */
bool at_start;
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
index e01bbe928ce..3cc462a8294 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
index 7169a13f328..782f20c8884 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject ViewEdgeIterator_Type;
/*---------------------------Python BPy_ViewEdgeIterator structure definition----------*/
typedef struct {
BPy_Iterator py_it;
- ViewEdgeInternal::ViewEdgeIterator *ve_it;
+ Freestyle::ViewEdgeInternal::ViewEdgeIterator *ve_it;
} BPy_ViewEdgeIterator;
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp
index 735746e33be..924045c9702 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
index 7a13f6d2c72..c6b1a123324 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
@@ -38,7 +38,7 @@ extern PyTypeObject orientedViewEdgeIterator_Type;
/*---------------------------Python BPy_orientedViewEdgeIterator structure definition----------*/
typedef struct {
BPy_Iterator py_it;
- ViewVertexInternal::orientedViewEdgeIterator *ove_it;
+ Freestyle::ViewVertexInternal::orientedViewEdgeIterator *ove_it;
bool reversed;
bool at_start;
} BPy_orientedViewEdgeIterator;
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
index c3b98d12918..6b3a20dbd9b 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
index 50fc9938a87..fd9b3951c6b 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
index e1198266a98..756a6e46c0d 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
@@ -28,6 +28,8 @@ extern "C" {
#include "../../../../python/generic/py_capi_utils.h"
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
index e8790df2dd0..a2540e53425 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
index 8fb6e26d8d7..7792fad3a68 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
index 2b108226e90..364f2ad72c2 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
index 0174107f27f..6ffcfec4f69 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
index b5c200c17b1..11153b9dfc5 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
index d1c3219b079..d6619934c16 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
index 7d1efebe71f..9f9c6e540dc 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
index f13930bd4b3..f91e5deacf7 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
index 48c63554f06..d087f6065b5 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
index 5f0a0bfb305..ed456230682 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
index 3d30fb4e11b..de9e67a93b2 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
index 876dd5f2f63..b975c1bb703 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
@@ -27,6 +27,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
index bd70d41717b..2c8451da43d 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
index fd7f5fabe77..cbbaaf2f82b 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
index ed575b12b8d..b52e10d21c7 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
index 5ce96212031..eec01c1ebb6 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
@@ -38,6 +38,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
index 60ebc646d74..abfc2609523 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
@@ -36,7 +36,7 @@ extern PyTypeObject UnaryFunction0DDouble_Type;
/*---------------------------Python BPy_UnaryFunction0DDouble structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<double> *uf0D_double;
+ Freestyle::UnaryFunction0D<double> *uf0D_double;
} BPy_UnaryFunction0DDouble;
/*---------------------------Python BPy_UnaryFunction0DDouble visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
index 8c988d55c91..6126ff571e6 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
index 9ce4b3bfd0b..83abc003393 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
@@ -38,7 +38,7 @@ extern PyTypeObject UnaryFunction0DEdgeNature_Type;
/*---------------------------Python BPy_UnaryFunction0DEdgeNature structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<Nature::EdgeNature> *uf0D_edgenature;
+ Freestyle::UnaryFunction0D<Freestyle::Nature::EdgeNature> *uf0D_edgenature;
} BPy_UnaryFunction0DEdgeNature;
/*---------------------------Python BPy_UnaryFunction0DEdgeNature visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
index 25b19e84b60..6b843817197 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
@@ -34,6 +34,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
index fd221201d99..a4c401f3dcd 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
@@ -36,7 +36,7 @@ extern PyTypeObject UnaryFunction0DFloat_Type;
/*---------------------------Python BPy_UnaryFunction0DFloat structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<float> *uf0D_float;
+ Freestyle::UnaryFunction0D<float> *uf0D_float;
} BPy_UnaryFunction0DFloat;
/*---------------------------Python BPy_UnaryFunction0DFloat visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
index b2426cab572..74f4ac9d392 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
index 14e5d48ce43..b13c976f0ac 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
@@ -38,7 +38,7 @@ extern PyTypeObject UnaryFunction0DId_Type;
/*---------------------------Python BPy_UnaryFunction0DId structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<Id> *uf0D_id;
+ Freestyle::UnaryFunction0D<Freestyle::Id> *uf0D_id;
} BPy_UnaryFunction0DId;
/*---------------------------Python BPy_UnaryFunction0DId visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
index 77f89265ba4..382dfdbd72d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
index bbd53c409eb..72054713a66 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
@@ -38,7 +38,7 @@ extern PyTypeObject UnaryFunction0DMaterial_Type;
/*---------------------------Python BPy_UnaryFunction0DMaterial structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<FrsMaterial> *uf0D_material;
+ Freestyle::UnaryFunction0D<Freestyle::FrsMaterial> *uf0D_material;
} BPy_UnaryFunction0DMaterial;
/*---------------------------Python BPy_UnaryFunction0DMaterial visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
index 52f990502ef..87241708d9c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
index 1a466ffc673..2958d10994c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
@@ -36,7 +36,7 @@ extern PyTypeObject UnaryFunction0DUnsigned_Type;
/*---------------------------Python BPy_UnaryFunction0DUnsigned structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<unsigned int> *uf0D_unsigned;
+ Freestyle::UnaryFunction0D<unsigned int> *uf0D_unsigned;
} BPy_UnaryFunction0DUnsigned;
/*---------------------------Python BPy_UnaryFunction0DUnsigned visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
index 45e1144cd32..b1451a89854 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
index 6c3d5fc85cc..2e570adbaee 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
@@ -23,7 +23,6 @@
#include "../BPy_UnaryFunction0D.h"
#include "../../geometry/Geom.h"
-using namespace Geometry;
#ifdef __cplusplus
extern "C" {
@@ -39,7 +38,7 @@ extern PyTypeObject UnaryFunction0DVec2f_Type;
/*---------------------------Python BPy_UnaryFunction0DVec2f structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<Vec2f> *uf0D_vec2f;
+ Freestyle::UnaryFunction0D<Freestyle::Geometry::Vec2f> *uf0D_vec2f;
} BPy_UnaryFunction0DVec2f;
/*---------------------------Python BPy_UnaryFunction0DVec2f visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
index 18eeae86dd7..65b5f56f61c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
index 4be9b170311..6334988a0ef 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
@@ -23,7 +23,6 @@
#include "../BPy_UnaryFunction0D.h"
#include "../../geometry/Geom.h"
-using namespace Geometry;
#ifdef __cplusplus
extern "C" {
@@ -39,7 +38,7 @@ extern PyTypeObject UnaryFunction0DVec3f_Type;
/*---------------------------Python BPy_UnaryFunction0DVec3f structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<Vec3f> *uf0D_vec3f;
+ Freestyle::UnaryFunction0D<Freestyle::Geometry::Vec3f> *uf0D_vec3f;
} BPy_UnaryFunction0DVec3f;
/*---------------------------Python BPy_UnaryFunction0DVec3f visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
index 28c4425b2a4..0c0c4930245 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
@@ -29,6 +29,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
index 2a36ae21002..4e49374273f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
@@ -40,7 +40,7 @@ extern PyTypeObject UnaryFunction0DVectorViewShape_Type;
* definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<std::vector<ViewShape *>> *uf0D_vectorviewshape;
+ Freestyle::UnaryFunction0D<std::vector<Freestyle::ViewShape *>> *uf0D_vectorviewshape;
} BPy_UnaryFunction0DVectorViewShape;
/*---------------------------Python BPy_UnaryFunction0DVectorViewShape visible
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
index 75773aaa8d0..d5122b27b35 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
index 8a8dcdceb1f..7a3c27a30c1 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
@@ -38,7 +38,7 @@ extern PyTypeObject UnaryFunction0DViewShape_Type;
/*---------------------------Python BPy_UnaryFunction0DViewShape structure definition----------*/
typedef struct {
BPy_UnaryFunction0D py_uf0D;
- UnaryFunction0D<ViewShape *> *uf0D_viewshape;
+ Freestyle::UnaryFunction0D<Freestyle::ViewShape *> *uf0D_viewshape;
} BPy_UnaryFunction0DViewShape;
/*---------------------------Python BPy_UnaryFunction0DViewShape visible prototypes-----------*/
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 b59e72e23d2..384d633fb2d 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 9f7f2b234f7..2c76f6f303a 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 1cd1a4ab8ac..6de53794228 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 60cfed83713..5baf1ba448e 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 063f1651486..864e8573043 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 b0188cd0244..b2cc62f6904 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 ba890477782..2a9b521907d 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 531020dc32a..e5e50dfcd4c 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 cb36e388306..71dda2e2c32 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 ca306a55d1e..0bf7f0e7fa4 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 6a688212239..0c4abc60981 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 8efaaf1b699..a87e64ee2ce 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 e13c990685f..52e0021d3b0 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 43cbb433bdd..98422fb45f3 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 24bfe3be985..f60115a4240 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 84a985a134d..822c3256fd9 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 247473dcb41..06d759f0737 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 e82b5f1c557..656749dfdff 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 b4760d10b2c..e547ebacf7e 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 d4c735e3572..8afeaed8518 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 6d5f1ed80c3..d9ab0edb53c 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 bbf2aee5204..125d0b8212d 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 54401153d37..ed0782edb22 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 88ca0579870..f1dadedf183 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 d6e00988e68..aca638ab972 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 ddff11d7916..8fe266c4f19 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
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
index 57b2d61d5c1..ad20dc79d71 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
@@ -43,6 +43,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
index 1fb42a18337..a57e42ce528 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
@@ -36,7 +36,7 @@ extern PyTypeObject UnaryFunction1DDouble_Type;
/*---------------------------Python BPy_UnaryFunction1DDouble structure definition----------*/
typedef struct {
BPy_UnaryFunction1D py_uf1D;
- UnaryFunction1D<double> *uf1D_double;
+ Freestyle::UnaryFunction1D<double> *uf1D_double;
} BPy_UnaryFunction1DDouble;
/*---------------------------Python BPy_UnaryFunction1DDouble visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
index a987dbb67f5..44937b3ebcc 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
index 886eb469d51..4227cc47efa 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
@@ -38,7 +38,7 @@ extern PyTypeObject UnaryFunction1DEdgeNature_Type;
/*---------------------------Python BPy_UnaryFunction1DEdgeNature structure definition----------*/
typedef struct {
BPy_UnaryFunction1D py_uf1D;
- UnaryFunction1D<Nature::EdgeNature> *uf1D_edgenature;
+ Freestyle::UnaryFunction1D<Freestyle::Nature::EdgeNature> *uf1D_edgenature;
} BPy_UnaryFunction1DEdgeNature;
/*---------------------------Python BPy_UnaryFunction1DEdgeNature visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
index 66499c68c65..2fc4cd4f2cb 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
index 8b977c9c96a..8be928eba77 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
@@ -36,7 +36,7 @@ extern PyTypeObject UnaryFunction1DFloat_Type;
/*---------------------------Python BPy_UnaryFunction1DFloat structure definition----------*/
typedef struct {
BPy_UnaryFunction1D py_uf1D;
- UnaryFunction1D<float> *uf1D_float;
+ Freestyle::UnaryFunction1D<float> *uf1D_float;
} BPy_UnaryFunction1DFloat;
/*---------------------------Python BPy_UnaryFunction1DFloat visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
index 54c5c786367..d5211d66d16 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
index 9149275b610..30fe050c2ad 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
@@ -36,7 +36,7 @@ extern PyTypeObject UnaryFunction1DUnsigned_Type;
/*---------------------------Python BPy_UnaryFunction1DUnsigned structure definition----------*/
typedef struct {
BPy_UnaryFunction1D py_uf1D;
- UnaryFunction1D<unsigned int> *uf1D_unsigned;
+ Freestyle::UnaryFunction1D<unsigned int> *uf1D_unsigned;
} BPy_UnaryFunction1DUnsigned;
/*---------------------------Python BPy_UnaryFunction1DUnsigned visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
index 8b23163fc95..684c9e189fe 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
@@ -31,6 +31,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
index b55f9af7c4d..2decb723a33 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
@@ -23,7 +23,6 @@
#include "../BPy_UnaryFunction1D.h"
#include "../../geometry/Geom.h"
-using namespace Geometry;
#ifdef __cplusplus
extern "C" {
@@ -39,7 +38,7 @@ extern PyTypeObject UnaryFunction1DVec2f_Type;
/*---------------------------Python BPy_UnaryFunction1DVec2f structure definition----------*/
typedef struct {
BPy_UnaryFunction1D py_uf1D;
- UnaryFunction1D<Vec2f> *uf1D_vec2f;
+ Freestyle::UnaryFunction1D<Freestyle::Geometry::Vec2f> *uf1D_vec2f;
} BPy_UnaryFunction1DVec2f;
/*---------------------------Python BPy_UnaryFunction1DVec2f visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
index 9b6a2445588..c45c61fd9ac 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
@@ -30,6 +30,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
index 9e4342979e4..9e7a899a371 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
@@ -23,7 +23,6 @@
#include "../BPy_UnaryFunction1D.h"
#include "../../geometry/Geom.h"
-using namespace Geometry;
#ifdef __cplusplus
extern "C" {
@@ -39,7 +38,7 @@ extern PyTypeObject UnaryFunction1DVec3f_Type;
/*---------------------------Python BPy_UnaryFunction1DVec3f structure definition----------*/
typedef struct {
BPy_UnaryFunction1D py_uf1D;
- UnaryFunction1D<Vec3f> *uf1D_vec3f;
+ Freestyle::UnaryFunction1D<Freestyle::Geometry::Vec3f> *uf1D_vec3f;
} BPy_UnaryFunction1DVec3f;
/*---------------------------Python BPy_UnaryFunction1DVec3f visible prototypes-----------*/
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
index c95595dc953..da8855a3a19 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
@@ -32,6 +32,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
index bfbcf5e451d..a8dfee7f9aa 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
@@ -40,7 +40,7 @@ extern PyTypeObject UnaryFunction1DVectorViewShape_Type;
* definition----------*/
typedef struct {
BPy_UnaryFunction1D py_uf1D;
- UnaryFunction1D<std::vector<ViewShape *>> *uf1D_vectorviewshape;
+ Freestyle::UnaryFunction1D<std::vector<Freestyle::ViewShape *>> *uf1D_vectorviewshape;
} BPy_UnaryFunction1DVectorViewShape;
/*---------------------------Python BPy_UnaryFunction1DVectorViewShape visible
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
index b258b0b27f7..5cfd12c42ff 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
@@ -32,6 +32,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//-------------------MODULE INITIALIZATION--------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
index 3a821bc2083..520ccc29c99 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
@@ -36,7 +36,7 @@ extern PyTypeObject UnaryFunction1DVoid_Type;
/*---------------------------Python BPy_UnaryFunction1DVoid structure definition----------*/
typedef struct {
BPy_UnaryFunction1D py_uf1D;
- UnaryFunction1D_void *uf1D_void;
+ Freestyle::UnaryFunction1D_void *uf1D_void;
} BPy_UnaryFunction1DVoid;
/*---------------------------Python BPy_UnaryFunction1DVoid visible prototypes-----------*/
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 205820d9a92..e203016aee5 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 d22a1ec99ef..620a74ddad1 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 f66bd4c668f..1d21f627305 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 2f408d45b74..60d6eeeef92 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 13455eb3a4c..ce0b9c0f231 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 fcf2bebc161..0190201ce37 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 5c352c670c1..d9c9b7af7a2 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 45c6a1b0fb7..2c5854a72e6 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 0c7276a13ec..6f00bc0f844 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 1f1c01a5344..b9b43c13b88 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 cfa06f9d8fd..f0b9fd192b0 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 985e10f2b83..ef59d19aba4 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 441ea2f5833..70b1a2cae2c 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 716cfbfe37a..51c04ba82b3 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 693c2453db2..f18d3cb647c 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 e9030625b10..4d5d3f18604 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 4ae2cd054e2..a2f233e6f6d 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 9feb07552ca..6d9bff89d81 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 400b5a95fcf..280f44e2e0c 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 7637153017f..4d7697d4078 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 d532268b294..aae7a2597b1 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 dd1492e940e..703e2e50955 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 c3750734efc..a3b5bb8fe05 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 85738684e44..23d254dd843 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
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 1f577820da4..cf94195cb01 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
@@ -28,6 +28,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
index 227aca2b5c6..f11a4d8c939 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
index 5f5c756b28d..018f44e4f07 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
index b3f9c225931..7c6b7b809f1 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
index f865fe5013d..0025b28137a 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
@@ -26,6 +26,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
index 154b44ff81a..34354349dfc 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
index 2bb9dbaf484..c9e8c80c3ce 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
index 7b9923d7b6c..3cc9a21c050 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
index ec1a02e13aa..58efd78619e 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
index b9a76f91c21..cca81e6bc6e 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
index 68f0ea7a913..a2eac6b41fe 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
index 362bcc4cea8..79b0fce790a 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
index 9329e3a7628..965945a1f79 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
@@ -24,6 +24,8 @@
extern "C" {
#endif
+using namespace Freestyle;
+
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h
index 1c959c43481..47a2e98418a 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.h
+++ b/source/blender/freestyle/intern/view_map/ViewMap.h
@@ -228,7 +228,7 @@ class ViewMap {
*/
ViewVertex *InsertViewVertex(SVertex *iVertex, vector<ViewEdge *> &newViewEdges);
- /* connects a FEdge to the graph trough a SVertex */
+ /* connects a FEdge to the graph through a SVertex */
// FEdge *Connect(FEdge *ioEdge, SVertex *ioVertex);
/* Clean temporary FEdges created by chaining */
@@ -1085,13 +1085,13 @@ class ViewEdge : public Interface1D {
return __B;
}
- /*! Returns the first FEdge that constitues this ViewEdge. */
+ /*! Returns the first FEdge that constitutes this ViewEdge. */
inline FEdge *fedgeA()
{
return _FEdgeA;
}
- /*! Returns the last FEdge that constitues this ViewEdge. */
+ /*! Returns the last FEdge that constitutes this ViewEdge. */
inline FEdge *fedgeB()
{
return _FEdgeB;
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
index 0ee491a071c..1984aceb51c 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
@@ -19,7 +19,7 @@
* and:
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
* Copyright (C) 2000-2003 Bruno Levy
- * Contact: Bruno Levy levy@loria.fr
+ * Contact: Bruno Levy <levy@loria.fr>
* ISA Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.h b/source/blender/freestyle/intern/winged_edge/Curvature.h
index d73674d02cd..0eefc57c3a2 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.h
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.h
@@ -19,7 +19,7 @@
* and:
* OGF/Graphite: Geometry and Graphics Programming Library + Utilities
* Copyright (C) 2000-2003 Bruno Levy
- * Contact: Bruno Levy levy@loria.fr
+ * Contact: Bruno Levy <levy@loria.fr>
* ISA Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh
index 5a7dfadf537..a854e63288d 100644
--- a/source/blender/functions/FN_cpp_type.hh
+++ b/source/blender/functions/FN_cpp_type.hh
@@ -929,4 +929,9 @@ inline std::unique_ptr<const CPPType> create_cpp_type(StringRef name, const T &d
static std::unique_ptr<const CPPType> cpp_type = blender::fn::create_cpp_type<TYPE_NAME>( \
STRINGIFY(IDENTIFIER), default_value); \
return *cpp_type; \
+ } \
+ /* Support using `CPPType::get<const T>()`. Otherwise the caller would have to remove const. */ \
+ template<> const blender::fn::CPPType &blender::fn::CPPType::get<const TYPE_NAME>() \
+ { \
+ return blender::fn::CPPType::get<TYPE_NAME>(); \
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
index e2f4d34ff40..f80ad60eb07 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
@@ -110,11 +110,11 @@ static bool dependsOnTime(GpencilModifierData *md)
return (mmd->flag & GP_NOISE_USE_RANDOM) != 0;
}
-static float *noise_table(int len, int seed)
+static float *noise_table(int len, int offset, int seed)
{
float *table = MEM_callocN(sizeof(float) * len, __func__);
for (int i = 0; i < len; i++) {
- table[i] = BLI_hash_int_01(BLI_hash_int_2d(seed, i + 1));
+ table[i] = BLI_hash_int_01(BLI_hash_int_2d(seed, i + offset + 1));
}
return table;
}
@@ -172,11 +172,19 @@ static void deformStroke(GpencilModifierData *md,
/* Sanitize as it can create out of bound reads. */
float noise_scale = clamp_f(mmd->noise_scale, 0.0f, 1.0f);
- int len = ceilf(gps->totpoints * noise_scale) + 1;
- float *noise_table_position = (mmd->factor > 0.0f) ? noise_table(len, seed + 2) : NULL;
- float *noise_table_strength = (mmd->factor_strength > 0.0f) ? noise_table(len, seed + 3) : NULL;
- float *noise_table_thickness = (mmd->factor_thickness > 0.0f) ? noise_table(len, seed) : NULL;
- float *noise_table_uvs = (mmd->factor_uvs > 0.0f) ? noise_table(len, seed + 4) : NULL;
+ int len = ceilf(gps->totpoints * noise_scale) + 2;
+ float *noise_table_position = (mmd->factor > 0.0f) ?
+ noise_table(len, (int)floor(mmd->noise_offset), seed + 2) :
+ NULL;
+ float *noise_table_strength = (mmd->factor_strength > 0.0f) ?
+ noise_table(len, (int)floor(mmd->noise_offset), seed + 3) :
+ NULL;
+ float *noise_table_thickness = (mmd->factor_thickness > 0.0f) ?
+ noise_table(len, (int)floor(mmd->noise_offset), seed) :
+ NULL;
+ float *noise_table_uvs = (mmd->factor_uvs > 0.0f) ?
+ noise_table(len, (int)floor(mmd->noise_offset), seed + 4) :
+ NULL;
/* Calculate stroke normal. */
if (gps->totpoints > 2) {
@@ -225,24 +233,27 @@ static void deformStroke(GpencilModifierData *md,
cross_v3_v3v3(vec2, vec1, normal);
normalize_v3(vec2);
- float noise = table_sample(noise_table_position, i * noise_scale);
+ float noise = table_sample(noise_table_position,
+ i * noise_scale + fractf(mmd->noise_offset));
madd_v3_v3fl(&pt->x, vec2, (noise * 2.0f - 1.0f) * weight * mmd->factor * 0.1f);
}
if (mmd->factor_thickness > 0.0f) {
- float noise = table_sample(noise_table_thickness, i * noise_scale);
+ float noise = table_sample(noise_table_thickness,
+ i * noise_scale + fractf(mmd->noise_offset));
pt->pressure *= max_ff(1.0f + (noise * 2.0f - 1.0f) * weight * mmd->factor_thickness, 0.0f);
CLAMP_MIN(pt->pressure, GPENCIL_STRENGTH_MIN);
}
if (mmd->factor_strength > 0.0f) {
- float noise = table_sample(noise_table_strength, i * noise_scale);
+ float noise = table_sample(noise_table_strength,
+ i * noise_scale + fractf(mmd->noise_offset));
pt->strength *= max_ff(1.0f - noise * weight * mmd->factor_strength, 0.0f);
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
}
if (mmd->factor_uvs > 0.0f) {
- float noise = table_sample(noise_table_uvs, i * noise_scale);
+ float noise = table_sample(noise_table_uvs, i * noise_scale + fractf(mmd->noise_offset));
pt->uv_rot += (noise * 2.0f - 1.0f) * weight * mmd->factor_uvs * M_PI_2;
CLAMP(pt->uv_rot, -M_PI_2, M_PI_2);
}
@@ -292,6 +303,8 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "factor_thickness", 0, IFACE_("Thickness"), ICON_NONE);
uiItemR(col, ptr, "factor_uvs", 0, IFACE_("UV"), ICON_NONE);
uiItemR(col, ptr, "noise_scale", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "noise_offset", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "seed", 0, NULL, ICON_NONE);
gpencil_modifier_panel_end(layout, ptr);
}
@@ -316,7 +329,6 @@ static void random_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetActive(layout, RNA_boolean_get(ptr, "random"));
uiItemR(layout, ptr, "step", 0, NULL, ICON_NONE);
- uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE);
}
static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 85981ac8043..018e192bf37 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -84,7 +84,7 @@ typedef struct GPUBatch {
GPUVertBuf *inst[GPU_BATCH_INST_VBO_MAX_LEN];
/** NULL if element list not needed */
GPUIndexBuf *elem;
- /** Bookeeping. */
+ /** Bookkeeping. */
eGPUBatchFlag flag;
/** Type of geometry to draw. */
GPUPrimType prim_type;
@@ -128,7 +128,7 @@ void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
eGPUShaderConfig sh_cfg);
/* Will only work after setting the batch program. */
-/* TODO(fclem): Theses needs to be replaced by GPU_shader_uniform_* with explicit shader. */
+/* TODO(fclem): These need to be replaced by GPU_shader_uniform_* with explicit shader. */
#define GPU_batch_uniform_1i(batch, name, x) GPU_shader_uniform_1i((batch)->shader, name, x);
#define GPU_batch_uniform_1b(batch, name, x) GPU_shader_uniform_1b((batch)->shader, name, x);
#define GPU_batch_uniform_1f(batch, name, x) GPU_shader_uniform_1f((batch)->shader, name, x);
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index c0f91756bf6..8c6592adf6d 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -20,7 +20,7 @@
/** \file
* \ingroup gpu
*
- * GPU Framebuffer
+ * GPU Frame-buffer
* - this is a wrapper for an OpenGL framebuffer object (FBO). in practice
* multiple FBO's may be created.
* - actual FBO creation & config is deferred until GPU_framebuffer_bind or
@@ -79,7 +79,7 @@ GPUFrameBuffer *GPU_framebuffer_back_get(void);
} \
} while (0)
-/* Framebuffer setup : You need to call GPU_framebuffer_bind for these
+/* Frame-buffer setup: You need to call #GPU_framebuffer_bind for these
* to be effective. */
void GPU_framebuffer_texture_attach_ex(GPUFrameBuffer *gpu_fb, GPUAttachment attachment, int slot);
@@ -154,7 +154,7 @@ void GPU_framebuffer_texture_layer_attach(
void GPU_framebuffer_texture_cubeface_attach(
GPUFrameBuffer *fb, GPUTexture *tex, int slot, int face, int mip);
-/* Framebuffer operations */
+/* Frame-buffer operations. */
void GPU_framebuffer_viewport_set(GPUFrameBuffer *fb, int x, int y, int w, int h);
void GPU_framebuffer_viewport_get(GPUFrameBuffer *fb, int r_viewport[4]);
diff --git a/source/blender/gpu/GPU_index_buffer.h b/source/blender/gpu/GPU_index_buffer.h
index 0c71dd539a6..76aab3c196b 100644
--- a/source/blender/gpu/GPU_index_buffer.h
+++ b/source/blender/gpu/GPU_index_buffer.h
@@ -70,7 +70,7 @@ void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem);
GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *);
void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, GPUIndexBuf *);
-/* Create a subrange of an existing indexbuffer. */
+/* Create a sub-range of an existing index-buffer. */
GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *elem_src, uint start, uint length);
void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem,
GPUIndexBuf *elem_src,
diff --git a/source/blender/gpu/GPU_platform.h b/source/blender/gpu/GPU_platform.h
index bb7e1d58041..c457b829bf7 100644
--- a/source/blender/gpu/GPU_platform.h
+++ b/source/blender/gpu/GPU_platform.h
@@ -34,6 +34,7 @@ typedef enum eGPUDeviceType {
GPU_DEVICE_ATI = (1 << 1),
GPU_DEVICE_INTEL = (1 << 2),
GPU_DEVICE_INTEL_UHD = (1 << 3),
+ GPU_DEVICE_APPLE = (1 << 3),
GPU_DEVICE_SOFTWARE = (1 << 4),
GPU_DEVICE_UNKNOWN = (1 << 5),
GPU_DEVICE_ANY = (0xff),
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 55716b584c3..9824c7016dc 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -29,7 +29,7 @@ extern "C" {
struct GPUVertBuf;
-/** Opaque type hidding blender::gpu::Shader */
+/** Opaque type hiding #blender::gpu::Shader */
typedef struct GPUShader GPUShader;
typedef enum eGPUShaderTFBType {
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index f5a1ccbc40b..0687f271670 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -46,7 +46,7 @@ ENUM_OPERATORS(eGPUBarrier, GPU_BARRIER_TEXTURE_FETCH)
/**
* Defines the fixed pipeline blending equation.
* SRC is the output color from the shader.
- * DST is the color from the framebuffer.
+ * DST is the color from the frame-buffer.
* The blending equation is :
* (SRC * A) + (DST * B).
* The blend mode will modify the A and B parameters.
@@ -64,7 +64,7 @@ typedef enum eGPUBlend {
* NOTE: Does not modify alpha. */
GPU_BLEND_INVERT,
/** Order independent transparency.
- * NOTE: Cannot be used as is. Needs special setup (framebuffer, shader ...). */
+ * NOTE: Cannot be used as is. Needs special setup (frame-buffer, shader ...). */
GPU_BLEND_OIT,
/** Special blend to add color under and multiply dst color by src alpha. */
GPU_BLEND_BACKGROUND,
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 91119bd05a1..da2d2639440 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -77,12 +77,12 @@ void GPU_samplers_update(void);
*/
/* Wrapper to supported OpenGL/Vulkan texture internal storage
- * If you need a type just uncomment it. Be aware that some formats
- * are not supported by renderbuffers. All of the following formats
+ * If you need a type just un-comment it. Be aware that some formats
+ * are not supported by render-buffers. All of the following formats
* are part of the OpenGL 3.3 core
* specification. */
typedef enum eGPUTextureFormat {
- /* Formats texture & renderbuffer */
+ /* Formats texture & render-buffer. */
GPU_RGBA8UI,
GPU_RGBA8I,
GPU_RGBA8,
diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h
index eeaebd3fae5..aae58de533b 100644
--- a/source/blender/gpu/GPU_vertex_buffer.h
+++ b/source/blender/gpu/GPU_vertex_buffer.h
@@ -34,7 +34,7 @@ typedef enum {
GPU_VERTBUF_INVALID = 0,
/** Was init with a vertex format. */
GPU_VERTBUF_INIT = (1 << 0),
- /** Data has been touched and need to be reuploaded. */
+ /** Data has been touched and need to be re-uploaded. */
GPU_VERTBUF_DATA_DIRTY = (1 << 1),
/** The buffer has been created inside GPU memory. */
GPU_VERTBUF_DATA_UPLOADED = (1 << 2),
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 84da95f6fee..a2072e504fd 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -109,7 +109,7 @@ static GPUPass *gpu_pass_cache_resolve_collision(GPUPass *pass,
uint32_t hash)
{
BLI_spin_lock(&pass_cache_spin);
- /* Collision, need to strcmp the whole shader. */
+ /* Collision, need to `strcmp` the whole shader. */
for (; pass && (pass->hash == hash); pass = pass->next) {
if ((defs != NULL) && (!STREQ(pass->defines, defs))) { /* Pass */
}
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index ffa7a38faa6..82753b44c51 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -93,7 +93,7 @@ class Context {
bool is_active_on_thread(void);
};
-/* Syntacting suggar. */
+/* Syntactic sugar. */
static inline GPUContext *wrap(Context *ctx)
{
return reinterpret_cast<GPUContext *>(ctx);
diff --git a/source/blender/gpu/intern/gpu_drawlist_private.hh b/source/blender/gpu/intern/gpu_drawlist_private.hh
index 98603299d62..393307e6ee5 100644
--- a/source/blender/gpu/intern/gpu_drawlist_private.hh
+++ b/source/blender/gpu/intern/gpu_drawlist_private.hh
@@ -42,7 +42,7 @@ class DrawList {
virtual void submit() = 0;
};
-/* Syntacting suggar. */
+/* Syntactic sugar. */
static inline GPUDrawList *wrap(DrawList *vert)
{
return reinterpret_cast<GPUDrawList *>(vert);
diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc
index d5d7994a154..2e183f52eea 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.cc
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -359,7 +359,7 @@ void GPU_framebuffer_viewport_reset(GPUFrameBuffer *gpu_fb)
unwrap(gpu_fb)->viewport_reset();
}
-/* ---------- Framebuffer Operations ----------- */
+/* ---------- Frame-buffer Operations ----------- */
void GPU_framebuffer_clear(GPUFrameBuffer *gpu_fb,
eGPUFrameBufferBits buffers,
diff --git a/source/blender/gpu/intern/gpu_framebuffer_private.hh b/source/blender/gpu/intern/gpu_framebuffer_private.hh
index 7afa56bfe3d..d63d72cf4f7 100644
--- a/source/blender/gpu/intern/gpu_framebuffer_private.hh
+++ b/source/blender/gpu/intern/gpu_framebuffer_private.hh
@@ -20,12 +20,7 @@
/** \file
* \ingroup gpu
*
- * GPU Framebuffer
- * - this is a wrapper for an OpenGL framebuffer object (FBO). in practice
- * multiple FBO's may be created.
- * - actual FBO creation & config is deferred until GPU_framebuffer_bind or
- * GPU_framebuffer_check_valid to allow creation & config while another
- * opengl context is bound (since FBOs are not shared between ogl contexts).
+ * Private frame buffer API.
*/
#pragma once
@@ -210,7 +205,7 @@ class FrameBuffer {
};
};
-/* Syntacting suggar. */
+/* Syntactic sugar. */
static inline GPUFrameBuffer *wrap(FrameBuffer *vert)
{
return reinterpret_cast<GPUFrameBuffer *>(vert);
diff --git a/source/blender/gpu/intern/gpu_immediate_private.hh b/source/blender/gpu/intern/gpu_immediate_private.hh
index 9fcbe2bdc0b..98399897ea9 100644
--- a/source/blender/gpu/intern/gpu_immediate_private.hh
+++ b/source/blender/gpu/intern/gpu_immediate_private.hh
@@ -34,7 +34,7 @@ namespace blender::gpu {
class Immediate {
public:
- /** Pointer to the mapped buffer data for the currect vertex. */
+ /** Pointer to the mapped buffer data for the current vertex. */
uchar *vertex_data = NULL;
/** Current vertex index. */
uint vertex_idx = 0;
@@ -49,10 +49,10 @@ class Immediate {
GPUPrimType prim_type = GPU_PRIM_NONE;
GPUVertFormat vertex_format = {};
GPUShader *shader = NULL;
- /** Enforce strict vertex count (disabled when using immBeginAtMost). */
+ /** Enforce strict vertex count (disabled when using #immBeginAtMost). */
bool strict_vertex_len = true;
- /** Batch in construction when using immBeginBatch. */
+ /** Batch in construction when using #immBeginBatch. */
GPUBatch *batch = NULL;
/** Wide Line workaround. */
@@ -61,7 +61,7 @@ class Immediate {
GPUShader *prev_shader = NULL;
/** Builtin shader index. Used to test if the workaround can be done. */
eGPUBuiltinShader builtin_shader_bound = GPU_SHADER_TEXT;
- /** Uniform color: Kept here to update the wideline shader just before immBegin. */
+ /** Uniform color: Kept here to update the wide-line shader just before #immBegin. */
float uniform_color[4];
public:
diff --git a/source/blender/gpu/intern/gpu_index_buffer_private.hh b/source/blender/gpu/intern/gpu_index_buffer_private.hh
index 7054360d07f..2405db8664a 100644
--- a/source/blender/gpu/intern/gpu_index_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_index_buffer_private.hh
@@ -57,7 +57,7 @@ class IndexBuf {
uint32_t index_len_ = 0;
/** Base index: Added to all indices after fetching. Allows index compression. */
uint32_t index_base_ = 0;
- /** Bookeeping. */
+ /** Bookkeeping. */
bool is_init_ = false;
/** Is this object only a reference to a subrange of another IndexBuf. */
bool is_subrange_ = false;
@@ -96,7 +96,7 @@ class IndexBuf {
inline uint index_range(uint *r_min, uint *r_max);
};
-/* Syntacting suggar. */
+/* Syntactic sugar. */
static inline GPUIndexBuf *wrap(IndexBuf *indexbuf)
{
return reinterpret_cast<GPUIndexBuf *>(indexbuf);
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index 08da49c3475..bf91a5bbb4d 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -132,7 +132,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
case GPU_NODE_LINK_ATTR:
input->source = GPU_SOURCE_ATTR;
input->attr = link->attr;
- /* Failsafe handling if the same attribute is used with different datatypes for
+ /* Fail-safe handling if the same attribute is used with different data-types for
* some reason (only really makes sense with float/vec2/vec3/vec4 though). This
* can happen if mixing the generic Attribute node with specialized ones. */
CLAMP_MIN(input->attr->gputype, type);
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 66748b4146a..6cda7888712 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -269,7 +269,7 @@ typedef struct GPUPickState {
ListBase bufs;
} cache;
- /* Pickign methods */
+ /* Picking methods. */
union {
/* GPU_SELECT_PICK_ALL */
struct {
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index d47ad5e0100..97673e92bcf 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -106,7 +106,7 @@ void Shader::print_log(Span<const char *> sources, char *log, const char *stage,
error_line = error_char = -1;
if (log_line[0] >= '0' && log_line[0] <= '9') {
error_line = (int)strtol(log_line, &error_line_number_end, 10);
- /* Try to fetch the error caracter (not always available). */
+ /* Try to fetch the error character (not always available). */
if (ELEM(error_line_number_end[0], '(', ':') && error_line_number_end[1] != ' ') {
error_char = (int)strtol(error_line_number_end + 1, &log_line, 10);
}
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index 62513ffb8a7..942be84caae 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -41,7 +41,7 @@ typedef struct ShaderInput {
uint32_t name_offset;
uint32_t name_hash;
int32_t location;
- /** Defined at interface creation or in shader. Only for Samplers, UBOs and Vertex Attribs. */
+ /** Defined at interface creation or in shader. Only for Samplers, UBOs and Vertex Attributes. */
int32_t binding;
} ShaderInput;
@@ -226,7 +226,7 @@ inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const
for (int i = inputs_len - 1; i >= 0; i--) {
if (inputs[i].name_hash == name_hash) {
if ((i > 0) && UNLIKELY(inputs[i - 1].name_hash == name_hash)) {
- /* Hash colision resolve. */
+ /* Hash collision resolve. */
for (; i >= 0 && inputs[i].name_hash == name_hash; i--) {
if (STREQ(name, name_buffer_ + inputs[i].name_offset)) {
return inputs + i; /* not found */
diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
index 85427372559..d9327bbc0f4 100644
--- a/source/blender/gpu/intern/gpu_shader_private.hh
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -76,7 +76,7 @@ class Shader {
void print_log(Span<const char *> sources, char *log, const char *stage, const bool error);
};
-/* Syntacting suggar. */
+/* Syntactic sugar. */
static inline GPUShader *wrap(Shader *vert)
{
return reinterpret_cast<GPUShader *>(vert);
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index e158601a25c..782d25747bb 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -165,6 +165,11 @@ void GPU_depth_range(float near, float far)
copy_v2_fl2(state.depth_range, near, far);
}
+/**
+ * \note By convention, this is set as needed and not reset back to 1.0.
+ * This means code that draws lines must always set the line width beforehand,
+ * but is not expected to restore it's previous value.
+ */
void GPU_line_width(float width)
{
width = max_ff(1.0f, width * PIXELSIZE);
diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh
index cda1b591bb1..b79350a6506 100644
--- a/source/blender/gpu/intern/gpu_state_private.hh
+++ b/source/blender/gpu/intern/gpu_state_private.hh
@@ -101,16 +101,16 @@ union GPUStateMutable {
/** Positive if using program point size. */
/* TODO(fclem): should be passed as uniform to all shaders. */
float point_size;
- /** Not supported on every platform. Prefer using wideline shader. */
+ /** Not supported on every platform. Prefer using wide-line shader. */
float line_width;
/** Mutable stencil states. */
uint8_t stencil_write_mask;
uint8_t stencil_compare_mask;
uint8_t stencil_reference;
uint8_t _pad0;
- /* IMPORTANT: ensure x64 stuct alignment. */
+ /* IMPORTANT: ensure x64 struct alignment. */
};
- /* Here to allow fast bitwise ops. */
+ /* Here to allow fast bit-wise ops. */
uint64_t data[9];
};
diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh
index 4197d5c55fc..400a36559da 100644
--- a/source/blender/gpu/intern/gpu_texture_private.hh
+++ b/source/blender/gpu/intern/gpu_texture_private.hh
@@ -83,11 +83,11 @@ class Texture {
protected:
/* ---- Texture format (immutable after init). ---- */
- /** Width & Height & Depth. For cubemap arrays, d is number of facelayers. */
+ /** Width & Height & Depth. For cube-map arrays, d is number of face-layers. */
int w_, h_, d_;
/** Internal data format. */
eGPUTextureFormat format_;
- /** Format caracteristics. */
+ /** Format characteristics. */
eGPUTextureFormatFlag format_flag_;
/** Texture type. */
eGPUTextureType type_;
@@ -101,7 +101,7 @@ class Texture {
/** For debugging */
char name_[DEBUG_NAME_LEN];
- /** Framebuffer references to update on deletion. */
+ /** Frame-buffer references to update on deletion. */
GPUAttachmentType fb_attachment_[GPU_TEX_MAX_FBO_ATTACHED];
FrameBuffer *fb_[GPU_TEX_MAX_FBO_ATTACHED];
@@ -245,7 +245,7 @@ class Texture {
virtual bool init_internal(GPUVertBuf *vbo) = 0;
};
-/* Syntacting suggar. */
+/* Syntactic sugar. */
static inline GPUTexture *wrap(Texture *vert)
{
return reinterpret_cast<GPUTexture *>(vert);
diff --git a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
index 826bdd9f8d5..e8fc1343eaf 100644
--- a/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_uniform_buffer_private.hh
@@ -65,7 +65,7 @@ class UniformBuf {
}
};
-/* Syntacting suggar. */
+/* Syntactic sugar. */
static inline GPUUniformBuf *wrap(UniformBuf *vert)
{
return reinterpret_cast<GPUUniformBuf *>(vert);
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
index da8b02c5c66..67a09f6f83c 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
@@ -62,7 +62,7 @@ class VertBuf {
void init(const GPUVertFormat *format, GPUUsageType usage);
void clear(void);
- /* Data manament */
+ /* Data management. */
void allocate(uint vert_len);
void resize(uint vert_len);
void upload(void);
@@ -105,7 +105,7 @@ class VertBuf {
virtual void duplicate_data(VertBuf *dst) = 0;
};
-/* Syntacting suggar. */
+/* Syntactic sugar. */
static inline GPUVertBuf *wrap(VertBuf *vert)
{
return reinterpret_cast<GPUVertBuf *>(vert);
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 014c70033fc..8498da11507 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -105,7 +105,7 @@ uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len)
static uchar copy_attr_name(GPUVertFormat *format, const char *name)
{
- /* strncpy does 110% of what we need; let's do exactly 100% */
+ /* `strncpy` does 110% of what we need; let's do exactly 100% */
uchar name_offset = format->name_offset;
char *name_copy = format->names + name_offset;
uint available = GPU_VERT_ATTR_NAMES_BUF_LEN - name_offset;
@@ -162,7 +162,7 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format,
assert(comp_len != 8 && comp_len != 12 && comp_len != 16);
}
#endif
- format->name_len++; /* multiname support */
+ format->name_len++; /* Multi-name support. */
const uint attr_id = format->attr_len++;
GPUVertAttr *attr = &format->attrs[attr_id];
@@ -186,7 +186,7 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
assert(format->name_len < GPU_VERT_FORMAT_MAX_NAMES); /* there's room for more */
assert(attr->name_len < GPU_VERT_ATTR_MAX_NAMES);
#endif
- format->name_len++; /* multiname support */
+ format->name_len++; /* Multi-name support. */
attr->names[attr->name_len++] = copy_attr_name(format, alias);
}
@@ -200,7 +200,7 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
*
* WARNING: this function creates a lot of aliases/attributes, make sure to keep the attribute
* name short to avoid overflowing the name-buffer.
- * */
+ */
void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count)
{
/* Sanity check. Maximum can be upgraded if needed. */
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 205ba1d06d6..c118145ebd6 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -86,10 +86,10 @@ struct GPUViewport {
int size[2];
int flag;
- /* Set the active view (for stereoscoptic viewport rendering). */
+ /* Set the active view (for stereoscopic viewport rendering). */
int active_view;
- /* If engine_handles mismatch we free all ViewportEngineData in this viewport. */
+ /* If engine_handles mismatch we free all #ViewportEngineData in this viewport. */
struct {
void *handle;
ViewportEngineData *data;
@@ -589,7 +589,7 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport,
/* Restore. */
view_settings->curve_mapping = tmp_curve_mapping;
viewport->view_settings.curve_mapping = tmp_curve_mapping_vp;
- /* Only copy curvemapping if needed. Avoid uneeded OCIO cache miss. */
+ /* Only copy curve-mapping if needed. Avoid unneeded OCIO cache miss. */
if (tmp_curve_mapping && viewport->view_settings.curve_mapping == NULL) {
BKE_color_managed_view_settings_free(&viewport->view_settings);
viewport->view_settings.curve_mapping = BKE_curvemapping_copy(tmp_curve_mapping);
@@ -820,7 +820,7 @@ void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
const float w = (float)GPU_texture_width(color);
const float h = (float)GPU_texture_height(color);
- /* We allow rects with min/max swapped, but we also need coorectly assigned coordinates. */
+ /* We allow rects with min/max swapped, but we also need correctly assigned coordinates. */
rcti sanitized_rect = *rect;
BLI_rcti_sanitize(&sanitized_rect);
@@ -974,7 +974,7 @@ static void gpu_viewport_passes_free(PassList *psl, int psl_len)
memset(psl->passes, 0, sizeof(*psl->passes) * psl_len);
}
-/* Must be executed inside Drawmanager Opengl Context. */
+/* Must be executed inside Draw-manager OpenGL Context. */
void GPU_viewport_free(GPUViewport *viewport)
{
gpu_viewport_engines_data_free(viewport);
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index 1d76b07c966..ef7788194a1 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -96,6 +96,11 @@ void GLBackend::platform_init()
GPG.device = GPU_DEVICE_SOFTWARE;
GPG.driver = GPU_DRIVER_SOFTWARE;
}
+ else if (strstr(vendor, "Apple")) {
+ /* Apple Silicon. */
+ GPG.device = GPU_DEVICE_APPLE;
+ GPG.driver = GPU_DRIVER_OFFICIAL;
+ }
else if (strstr(renderer, "Apple Software Renderer")) {
GPG.device = GPU_DEVICE_SOFTWARE;
GPG.driver = GPU_DRIVER_SOFTWARE;
@@ -244,15 +249,16 @@ static void detect_workarounds()
if (!GLEW_VERSION_4_0) {
GLContext::base_instance_support = false;
}
- /* The renderers include:
- * Mobility Radeon HD 5000;
- * Radeon HD 7500M;
- * Radeon HD 7570M;
- * Radeon HD 7600M;
- * And many others... */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) &&
(strstr(version, "4.5.13399") || strstr(version, "4.5.13417") ||
- strstr(version, "4.5.13422"))) {
+ strstr(version, "4.5.13422") || strstr(version, "4.5.13467"))) {
+ /* The renderers include:
+ * Radeon HD 5000;
+ * Radeon HD 7500M;
+ * Radeon HD 7570M;
+ * Radeon HD 7600M;
+ * Radeon R5 Graphics;
+ * And others... */
GLContext::unused_fb_slot_workaround = true;
GCaps.mip_render_workaround = true;
GCaps.shader_image_load_store_support = false;
@@ -302,7 +308,7 @@ static void detect_workarounds()
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) && !GLEW_VERSION_4_5) {
GLContext::copy_image_support = false;
}
- /* Special fix for theses specific GPUs.
+ /* Special fix for these specific GPUs.
* Without this workaround, blender crashes on startup. (see T72098) */
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) &&
(strstr(renderer, "HD Graphics 620") || strstr(renderer, "HD Graphics 630"))) {
@@ -361,14 +367,14 @@ static void detect_workarounds()
}
}
- /* Some Intel drivers have issues with using mips as framebuffer targets if
- * GL_TEXTURE_MAX_LEVEL is higher than the target mip.
+ /* Some Intel drivers have issues with using mips as frame-buffer targets if
+ * GL_TEXTURE_MAX_LEVEL is higher than the target MIP.
* Only check at the end after all other workarounds because this uses the drawing code.
* Also after device/driver flags to avoid the check that causes pre GCN Radeon to crash. */
if (GCaps.mip_render_workaround == false) {
GCaps.mip_render_workaround = detect_mip_render_workaround();
}
- /* Disable multidraw if the base instance cannot be read. */
+ /* Disable multi-draw if the base instance cannot be read. */
if (GLContext::shader_draw_parameters_support == false) {
GLContext::multi_draw_indirect_support = false;
}
diff --git a/source/blender/gpu/opengl/gl_batch.hh b/source/blender/gpu/opengl/gl_batch.hh
index 0fadde7a70d..218b9ffe4b7 100644
--- a/source/blender/gpu/opengl/gl_batch.hh
+++ b/source/blender/gpu/opengl/gl_batch.hh
@@ -52,9 +52,9 @@ class GLVaoCache {
GLContext *context_ = NULL;
/** Last interface this batch was drawn with. */
GLShaderInterface *interface_ = NULL;
- /** Cached vao for the last interface. */
+ /** Cached VAO for the last interface. */
GLuint vao_id_ = 0;
- /** Used whend arb_base_instance is not supported. */
+ /** Used when arb_base_instance is not supported. */
GLuint vao_base_instance_ = 0;
int base_instance_ = 0;
diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc
index d766e6f0828..6c9c6e10774 100644
--- a/source/blender/gpu/opengl/gl_context.cc
+++ b/source/blender/gpu/opengl/gl_context.cc
@@ -108,7 +108,7 @@ GLContext::~GLContext()
BLI_assert(orphaned_vertarrays_.is_empty());
/* For now don't allow GPUFrameBuffers to be reuse in another context. */
BLI_assert(framebuffers_.is_empty());
- /* Delete vaos so the batch can be reused in another context. */
+ /* Delete VAO's so the batch can be reused in another context. */
for (GLVaoCache *cache : vao_caches_) {
cache->clear();
}
@@ -312,7 +312,7 @@ void GLContext::memory_statistics_get(int *r_total_mem, int *r_free_mem)
{
/* TODO(merwin): use Apple's platform API to get this info. */
if (GLEW_NVX_gpu_memory_info) {
- /* Teturned value in Kb. */
+ /* Returned value in Kb. */
glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, r_total_mem);
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, r_free_mem);
}
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index 66a3fdd3355..0222adaba25 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -43,7 +43,7 @@ class GLVaoCache;
class GLSharedOrphanLists {
public:
- /** Mutex for the bellow structures. */
+ /** Mutex for the below structures. */
std::mutex lists_mutex;
/** Buffers and textures are shared across context. Any context can free them. */
Vector<GLuint> textures;
@@ -87,17 +87,17 @@ class GLContext : public Context {
private:
/**
- * GPUBatch & GPUFramebuffer have references to the context they are from, in the case the
+ * #GPUBatch & #GPUFramebuffer have references to the context they are from, in the case the
* context is destroyed, we need to remove any reference to it.
*/
Set<GLVaoCache *> vao_caches_;
Set<GPUFrameBuffer *> framebuffers_;
- /** Mutex for the bellow structures. */
+ /** Mutex for the below structures. */
std::mutex lists_mutex_;
/** VertexArrays and framebuffers are not shared across context. */
Vector<GLuint> orphaned_vertarrays_;
Vector<GLuint> orphaned_framebuffers_;
- /** GLBackend onws this data. */
+ /** #GLBackend owns this data. */
GLSharedOrphanLists &shared_orphan_list_;
public:
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index 0914c117241..ac42a950945 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -363,7 +363,7 @@ namespace blender::gpu {
void GLContext::debug_group_begin(const char *name, int index)
{
if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) {
- /* Add 10 to avoid conlision with other indices from other possible callback layers. */
+ /* Add 10 to avoid collision with other indices from other possible callback layers. */
index += 10;
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, index, -1, name);
}
diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc
index cbb332388dc..aea19295311 100644
--- a/source/blender/gpu/opengl/gl_framebuffer.cc
+++ b/source/blender/gpu/opengl/gl_framebuffer.cc
@@ -142,13 +142,13 @@ bool GLFrameBuffer::check(char err_out[256])
#undef FORMAT_STATUS
- const char *format = "GPUFrameBuffer: frame-buffer status %s\n";
+ const char *format = "GPUFrameBuffer: %s status %s\n";
if (err_out) {
- BLI_snprintf(err_out, 256, format, err);
+ BLI_snprintf(err_out, 256, format, this->name_, err);
}
else {
- fprintf(stderr, format, err);
+ fprintf(stderr, format, this->name_, err);
}
return false;
diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh
index 95e67f5973c..7b2c73d7042 100644
--- a/source/blender/gpu/opengl/gl_framebuffer.hh
+++ b/source/blender/gpu/opengl/gl_framebuffer.hh
@@ -20,7 +20,7 @@
/** \file
* \ingroup gpu
*
- * Encapsulation of Framebuffer states (attached textures, viewport, scissors).
+ * Encapsulation of Frame-buffer states (attached textures, viewport, scissors).
*/
#pragma once
@@ -45,22 +45,22 @@ class GLFrameBuffer : public FrameBuffer {
private:
/** OpenGL handle. */
GLuint fbo_id_ = 0;
- /** Context the handle is from. Framebuffers are not shared accros contexts. */
+ /** Context the handle is from. Frame-buffers are not shared across contexts. */
GLContext *context_ = NULL;
/** State Manager of the same contexts. */
GLStateManager *state_manager_ = NULL;
/** Copy of the GL state. Contains ONLY color attachments enums for slot binding. */
GLenum gl_attachments_[GPU_FB_MAX_COLOR_ATTACHMENT];
- /** Internal framebuffers are immutable. */
+ /** Internal frame-buffers are immutable. */
bool immutable_;
- /** True is the framebuffer has its first color target using the GPU_SRGB8_A8 format. */
+ /** True is the frame-buffer has its first color target using the GPU_SRGB8_A8 format. */
bool srgb_;
- /** True is the framebuffer has been bound using the GL_FRAMEBUFFER_SRGB feature. */
+ /** True is the frame-buffer has been bound using the GL_FRAMEBUFFER_SRGB feature. */
bool enabled_srgb_ = false;
public:
/**
- * Create a conventional framebuffer to attach texture to.
+ * Create a conventional frame-buffer to attach texture to.
*/
GLFrameBuffer(const char *name);
diff --git a/source/blender/gpu/opengl/gl_primitive.hh b/source/blender/gpu/opengl/gl_primitive.hh
index 7cd0654bc2c..05a15017c66 100644
--- a/source/blender/gpu/opengl/gl_primitive.hh
+++ b/source/blender/gpu/opengl/gl_primitive.hh
@@ -20,7 +20,7 @@
/** \file
* \ingroup gpu
*
- * Encapsulation of Framebuffer states (attached textures, viewport, scissors).
+ * Encapsulation of Frame-buffer states (attached textures, viewport, scissors).
*/
#pragma once
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index 9533639b133..5870c645bf4 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -51,7 +51,7 @@ static inline int sampler_binding(int32_t program,
int32_t uniform_location,
int *sampler_len)
{
- /* Identify sampler uniforms and asign sampler units to them. */
+ /* Identify sampler uniforms and assign sampler units to them. */
GLint type;
glGetActiveUniformsiv(program, 1, &uniform_index, GL_UNIFORM_TYPE, &type);
@@ -106,7 +106,7 @@ static inline int image_binding(int32_t program,
int32_t uniform_location,
int *image_len)
{
- /* Identify image uniforms and asign image units to them. */
+ /* Identify image uniforms and assign image units to them. */
GLint type;
glGetActiveUniformsiv(program, 1, &uniform_index, GL_UNIFORM_TYPE, &type);
@@ -133,7 +133,7 @@ static inline int image_binding(int32_t program,
GLShaderInterface::GLShaderInterface(GLuint program)
{
- /* Necessary to make glUniform works. */
+ /* Necessary to make #glUniform works. */
glUseProgram(program);
GLint max_attr_name_len = 0, attr_len = 0;
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
index 643e46acc2d..651c3c22afa 100644
--- a/source/blender/gpu/opengl/gl_state.hh
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -42,7 +42,7 @@ class GLTexture;
*/
class GLStateManager : public StateManager {
public:
- /** Anothter reference to the active framebuffer. */
+ /** Another reference to the active frame-buffer. */
GLFrameBuffer *active_fb = nullptr;
private:
diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index 2e8d9dd6e1c..ef38e964c7b 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -32,7 +32,7 @@
#include "gl_backend.hh"
#include "gl_debug.hh"
#include "gl_state.hh"
-#include "gpu_vertex_buffer_private.hh" /* TODO shoud be gl_vertex_buffer.hh */
+#include "gpu_vertex_buffer_private.hh" /* TODO should be `gl_vertex_buffer.hh` */
#include "gl_texture.hh"
diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh
index e686a7defca..65a211e12a3 100644
--- a/source/blender/gpu/opengl/gl_texture.hh
+++ b/source/blender/gpu/opengl/gl_texture.hh
@@ -1,4 +1,3 @@
-
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,13 +19,6 @@
/** \file
* \ingroup gpu
- *
- * GPU Framebuffer
- * - this is a wrapper for an OpenGL framebuffer object (FBO). in practice
- * multiple FBO's may be created.
- * - actual FBO creation & config is deferred until GPU_framebuffer_bind or
- * GPU_framebuffer_check_valid to allow creation & config while another
- * opengl context is bound (since FBOs are not shared between ogl contexts).
*/
#pragma once
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 fb512a1f00e..81e0965fad3 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
@@ -57,7 +57,7 @@ in float dummy;
vec2 do_widget(void)
{
- /* Offset to avoid loosing pixels (mimics conservative rasterization). */
+ /* Offset to avoid losing pixels (mimics conservative rasterization). */
const vec2 ofs = vec2(0.5, -0.5);
lineWidth = abs(rect.x - recti.x);
vec2 emboss_ofs = vec2(0.0, -lineWidth);
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 3f444172499..eb31b0e9f87 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -1878,7 +1878,7 @@ static void execute_scene(struct Depsgraph *depsgraph,
/*---------------------------------------------------
* plugin interface
- * */
+ */
void itasc_initialize_tree(struct Depsgraph *depsgraph,
struct Scene *scene,
Object *ob,
diff --git a/source/blender/imbuf/IMB_metadata.h b/source/blender/imbuf/IMB_metadata.h
index 501bf9dfba1..652ce913ee5 100644
--- a/source/blender/imbuf/IMB_metadata.h
+++ b/source/blender/imbuf/IMB_metadata.h
@@ -35,7 +35,7 @@ struct anim;
* The metadata is a list of key/value pairs (both char *) that can me
* saved in the header of several image formats.
* Apart from some common keys like
- * 'Software' and 'Description' (png standard) we'll use keys within the
+ * 'Software' and 'Description' (PNG standard) we'll use keys within the
* Blender namespace, so should be called 'Blender::StampInfo' or 'Blender::FrameNum'
* etc...
*
diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h
index 08aa1936a6f..c92d764a104 100644
--- a/source/blender/imbuf/intern/IMB_allocimbuf.h
+++ b/source/blender/imbuf/intern/IMB_allocimbuf.h
@@ -32,7 +32,7 @@ struct ImBuf;
void imb_refcounter_lock_init(void);
void imb_refcounter_lock_exit(void);
-#ifdef WIN32
+#ifndef WIN32
void imb_mmap_lock_init(void);
void imb_mmap_lock_exit(void);
void imb_mmap_lock(void);
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 8dfb3ada7d6..90c863878ff 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -53,7 +53,7 @@ void imb_refcounter_lock_exit(void)
BLI_spin_end(&refcounter_spin);
}
-#ifdef WIN32
+#ifndef WIN32
static SpinLock mmap_spin;
void imb_mmap_lock_init(void)
@@ -197,7 +197,7 @@ void IMB_freezbuffloatImBuf(ImBuf *ibuf)
ibuf->mall &= ~IB_zbuffloat;
}
-/** Free all pixel data (assosiated with image size). */
+/** Free all pixel data (associated with image size). */
void imb_freerectImbuf_all(ImBuf *ibuf)
{
imb_freerectImBuf(ibuf);
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index c40e65b1c5c..3a7570cd320 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -1050,7 +1050,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ
int64_t pts_to_search = 0;
double frame_rate;
double pts_time_base;
- long long st_time;
+ int64_t st_time;
struct anim_index *tc_index = 0;
AVStream *v_st;
int new_frame_index = 0; /* To quiet gcc barking... */
@@ -1121,7 +1121,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ
ffmpeg_decode_video_frame_scan(anim, pts_to_search);
}
else if (position != anim->curposition + 1) {
- long long pos;
+ int64_t pos;
int ret;
if (tc_index) {
@@ -1145,7 +1145,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ
}
}
else {
- pos = (long long)(position - anim->preseek) * AV_TIME_BASE / frame_rate;
+ pos = (int64_t)(position - anim->preseek) * AV_TIME_BASE / frame_rate;
av_log(anim->pFormatCtx,
AV_LOG_DEBUG,
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp
index 00fa0111d1c..3b1b970fb3c 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.cpp
+++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp
@@ -400,7 +400,7 @@ void ColorBlock::boundsRangeAlpha(Color32 *start, Color32 *end) const
#endif
#if 0
-/** Sort colors by abosolute value in their 16 bit representation. */
+/** Sort colors by absolute value in their 16 bit representation. */
void ColorBlock::sortColorsByAbsoluteValue()
{
/* Dummy selection sort. */
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index 0271c7964b8..9c3d73bbb0d 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -25,7 +25,7 @@
* Original license from NVIDIA follows.
*/
-// This code is in the public domain -- castanyo@yahoo.es
+// This code is in the public domain -- <castanyo@yahoo.es>
#pragma once
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index cce264624ce..343c8cd8f64 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -425,7 +425,7 @@ static int check_pixel_assigned(
*
* When a mask is given, only effect pixels with a mask value of 1,
* defined as #BAKE_MASK_MARGIN in rendercore.c
- * */
+ */
void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
{
const int width = ibuf->x;
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index f8029c08bad..7ada0130059 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -115,7 +115,7 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, in
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);
bicubic_interpolation_color(in, outI, outF, u, v);
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index fb8c361d94b..cf27557d043 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -476,7 +476,7 @@ static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
r = image->comps[0].data;
a = (use_alpha) ? image->comps[1].data : NULL;
- /* grayscale 12bits+ */
+ /* Gray-scale 12bits+ */
if (use_alpha) {
a = image->comps[1].data;
PIXEL_LOOPER_BEGIN (rect_float) {
@@ -500,7 +500,7 @@ static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
g = image->comps[1].data;
b = image->comps[2].data;
- /* rgb or rgba 12bits+ */
+ /* RGB or RGBA 12bits+ */
if (use_alpha) {
a = image->comps[3].data;
PIXEL_LOOPER_BEGIN (rect_float) {
@@ -551,7 +551,7 @@ static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
g = image->comps[1].data;
b = image->comps[2].data;
- /* 8bit rgb or rgba */
+ /* 8bit RGB or RGBA */
if (use_alpha) {
a = image->comps[3].data;
PIXEL_LOOPER_BEGIN (rect_uchar) {
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 979e7703e81..2a9cb9af891 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -1108,7 +1108,7 @@ void IMB_exr_write_channels(void *handle)
const size_t num_pixels = ((size_t)data->width) * data->height;
half *rect_half = nullptr, *current_rect_half = nullptr;
- /* We allocate teporary storage for half pixels for all the channels at once. */
+ /* We allocate temporary storage for half pixels for all the channels at once. */
if (data->num_half_channels != 0) {
rect_half = (half *)MEM_mallocN(sizeof(half) * data->num_half_channels * num_pixels,
__func__);
@@ -1235,7 +1235,7 @@ void IMB_exr_read_channels(void *handle)
Header header = in.header();
Box2i dw = header.dataWindow();
- /* Insert all matching channel into framebuffer. */
+ /* Insert all matching channel into frame-buffer. */
FrameBuffer frameBuffer;
ExrChannel *echan;
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index f0daa4543e1..50210650f05 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -23,13 +23,13 @@
*/
#ifdef _WIN32
-# include "mmap_win.h"
# include <io.h>
# include <stddef.h>
# include <sys/types.h>
#endif
#include "BLI_fileops.h"
+#include "BLI_mmap.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -186,20 +186,19 @@ ImBuf *IMB_loadifffile(
size = BLI_file_descriptor_size(file);
imb_mmap_lock();
- mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
+ BLI_mmap_file *mmap_file = BLI_mmap_open(file);
imb_mmap_unlock();
-
- if (mem == (unsigned char *)-1) {
+ if (mmap_file == NULL) {
fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
return NULL;
}
+ mem = BLI_mmap_get_pointer(mmap_file);
+
ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
imb_mmap_lock();
- if (munmap(mem, size)) {
- fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
- }
+ BLI_mmap_free(mmap_file);
imb_mmap_unlock();
return ibuf;
@@ -292,14 +291,15 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int
size = BLI_file_descriptor_size(file);
imb_mmap_lock();
- mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
+ BLI_mmap_file *mmap_file = BLI_mmap_open(file);
imb_mmap_unlock();
-
- if (mem == (unsigned char *)-1) {
+ if (mmap_file == NULL) {
fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
return;
}
+ mem = BLI_mmap_get_pointer(mmap_file);
+
const ImFileType *type = IMB_file_type_from_ibuf(ibuf);
if (type != NULL) {
if (type->load_tile != NULL) {
@@ -308,9 +308,7 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int
}
imb_mmap_lock();
- if (munmap(mem, size)) {
- fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
- }
+ BLI_mmap_free(mmap_file);
imb_mmap_unlock();
}
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index a9833623250..d7cefbbd077 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -713,7 +713,7 @@ ImBuf *imb_loadtarga(const unsigned char *mem,
return ibuf;
}
- if (!ELEM(tga.imgtyp, 1, 9)) { /* happens sometimes (beuh) */
+ if (!ELEM(tga.imgtyp, 1, 9)) { /* happens sometimes (ugh) */
if (cmap) {
MEM_freeN(cmap);
cmap = NULL;
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 038c9950968..0d2080b5f0a 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -63,7 +63,7 @@
* because 'near' is disabled through BLI_windstuff */
# include "BLI_winstuff.h"
# include "utfconv.h"
-# include <direct.h> /* chdir */
+# include <direct.h> /* #chdir */
# include <shlobj.h>
#endif
diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c
index 486db07597f..0d1fa354b3e 100644
--- a/source/blender/imbuf/intern/thumbs_blend.c
+++ b/source/blender/imbuf/intern/thumbs_blend.c
@@ -57,7 +57,7 @@ ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const
/* Note: we should handle all previews for a same group at once, would avoid reopening
* `.blend` file for each and every ID. However, this adds some complexity,
* so keep it for later. */
- names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, &nnames);
+ names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, false, &nnames);
previews = BLO_blendhandle_get_previews(libfiledata, idcode, &nprevs);
BLO_blendhandle_close(libfiledata);
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 587d6ad9e7e..2fb14e40d9d 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -512,7 +512,7 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image)
}
if (success) {
- /* Code seems to be not needed for 16 bits tif, on PPC G5 OSX (ton) */
+ /* Code seems to be not needed for 16 bits TIFF, on PPC G5 OSX (ton) */
if (bitspersample < 16) {
if (ENDIAN_ORDER == B_ENDIAN) {
IMB_convert_rgba_to_abgr(tmpibuf);
@@ -806,7 +806,7 @@ bool imb_savetiff(ImBuf *ibuf, const char *filepath, int flags)
/* open TIFF file for writing */
if (flags & IB_mem) {
- /* bork at the creation of a TIFF in memory */
+ /* Failed to allocate TIFF in memory. */
fprintf(stderr,
"imb_savetiff: creation of in-memory TIFF files is "
"not yet supported.\n");
diff --git a/source/blender/io/alembic/exporter/abc_archive.cc b/source/blender/io/alembic/exporter/abc_archive.cc
index 68ad2089a3e..90a4baf97bc 100644
--- a/source/blender/io/alembic/exporter/abc_archive.cc
+++ b/source/blender/io/alembic/exporter/abc_archive.cc
@@ -112,7 +112,7 @@ static OArchive *create_archive(std::ofstream *abc_ostream,
*
* If 'time_relative' is true, samples are returned as time (in seconds) from params.frame_start.
* If 'time_relative' is false, samples are returned as fractional frames from 0.
- * */
+ */
static void get_shutter_samples(double scene_fps,
const AlembicExportParams &params,
int nr_of_samples,
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.h b/source/blender/io/alembic/exporter/abc_writer_mesh.h
index fdf2d3cc1e3..ed4fb4e4514 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.h
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.h
@@ -32,7 +32,7 @@ namespace blender::io::alembic {
/* Writer for Alembic geometry. Does not assume the object is a mesh object. */
class ABCGenericMeshWriter : public ABCAbstractWriter {
private:
- /* Either polymesh or subd is used, depending on is_subd_.
+ /* Either poly-mesh or subdivision-surface is used, depending on is_subd_.
* References to the schema must be kept, or Alembic will not properly write. */
Alembic::AbcGeom::OPolyMesh abc_poly_mesh_;
Alembic::AbcGeom::OPolyMeshSchema abc_poly_mesh_schema_;
diff --git a/source/blender/io/alembic/exporter/abc_writer_transform.cc b/source/blender/io/alembic/exporter/abc_writer_transform.cc
index 7fe9fd933c5..eff042d036d 100644
--- a/source/blender/io/alembic/exporter/abc_writer_transform.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_transform.cc
@@ -94,7 +94,7 @@ void ABCTransformWriter::do_write(HierarchyContext &context)
scale_mat[3][3] = args_.export_params->global_scale; /* also scale translation */
mul_m4_m4m4(parent_relative_matrix, parent_relative_matrix, scale_mat);
parent_relative_matrix[3][3] /=
- args_.export_params->global_scale; /* normalise the homogeneous component */
+ args_.export_params->global_scale; /* Normalize the homogeneous component. */
}
XformSample xform_sample;
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index 0b9636ffb70..8133f615080 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -521,7 +521,7 @@ static bool has_animated_geom_params(const ICompoundProperty arbGeomParams)
return false;
}
-/* Specialisation of has_animations() as defined in abc_reader_object.h. */
+/* Specialization of #has_animations() as defined in abc_reader_object.h. */
template<> bool has_animations(Alembic::AbcGeom::IPolyMeshSchema &schema, ImportSettings *settings)
{
if (settings->is_sequence || !schema.isConstant()) {
diff --git a/source/blender/io/alembic/intern/abc_util.cc b/source/blender/io/alembic/intern/abc_util.cc
index aa7beb37dc5..3d3ba0347c5 100644
--- a/source/blender/io/alembic/intern/abc_util.cc
+++ b/source/blender/io/alembic/intern/abc_util.cc
@@ -135,7 +135,7 @@ bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string
return prop.getPropertyHeader(name) != nullptr;
}
-typedef std::pair<Alembic::AbcCoreAbstract::index_t, float> index_time_pair_t;
+using index_time_pair_t = std::pair<Alembic::AbcCoreAbstract::index_t, float>;
float get_weight_and_index(float time,
const Alembic::AbcCoreAbstract::TimeSamplingPtr &time_sampling,
diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp
index 9f54bf2aa28..49f28325257 100644
--- a/source/blender/io/collada/AnimationImporter.cpp
+++ b/source/blender/io/collada/AnimationImporter.cpp
@@ -120,12 +120,12 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
COLLADAFW::FloatOrDoubleArray &intan = curve->getInTangentValues();
COLLADAFW::FloatOrDoubleArray &outtan = curve->getOutTangentValues();
- /* intangent */
+ /* In-tangent. */
unsigned int 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);
- /* outtangent */
+ /* Out-tangent. */
bez.vec[2][0] = bc_get_float_value(outtan, index) * fps;
bez.vec[2][1] = bc_get_float_value(outtan, index + 1);
if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER) {
diff --git a/source/blender/io/collada/ArmatureExporter.cpp b/source/blender/io/collada/ArmatureExporter.cpp
index 9bf1a4ae830..28f5f9d40bc 100644
--- a/source/blender/io/collada/ArmatureExporter.cpp
+++ b/source/blender/io/collada/ArmatureExporter.cpp
@@ -197,7 +197,7 @@ void ArmatureExporter::add_bone_node(Bone *bone,
add_bone_transform(ob_arm, bone, node);
- /* Write nodes of childobjects, remove written objects from list */
+ /* Write nodes of child-objects, remove written objects from list. */
std::vector<Object *>::iterator iter = child_objects.begin();
while (iter != child_objects.end()) {
@@ -219,7 +219,7 @@ void ArmatureExporter::add_bone_node(Bone *bone,
* single matrix the tweak must be applied
* to the result. */
if (export_settings.get_open_sim()) {
- /* Tweak objects parentinverse to match compatibility. */
+ /* Tweak objects parent-inverse to match compatibility. */
float temp[4][4];
copy_m4_m4(temp, bone->arm_mat);
diff --git a/source/blender/io/collada/ArmatureImporter.cpp b/source/blender/io/collada/ArmatureImporter.cpp
index 7eef5c3f5fb..5c3d6be589a 100644
--- a/source/blender/io/collada/ArmatureImporter.cpp
+++ b/source/blender/io/collada/ArmatureImporter.cpp
@@ -1108,7 +1108,7 @@ BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone,
}
if (!has_connect && this->import_settings->auto_connect) {
- /* auto connect only whyen parent has exactly one child*/
+ /* Auto connect only when parent has exactly one child. */
connect_type = sibcount == 1;
}
diff --git a/source/blender/io/collada/BCAnimationCurve.h b/source/blender/io/collada/BCAnimationCurve.h
index 27856dd55f4..a1597cd47be 100644
--- a/source/blender/io/collada/BCAnimationCurve.h
+++ b/source/blender/io/collada/BCAnimationCurve.h
@@ -133,7 +133,7 @@ class BCAnimationCurve {
void get_frames(BCFrames &frames) const;
- /* Curve edit functions create a copy of the underlaying FCurve */
+ /* Curve edit functions create a copy of the underlying #FCurve. */
FCurve *get_edit_fcurve();
bool add_value_from_rna(const int frame);
bool add_value_from_matrix(const BCSample &sample, const int frame);
diff --git a/source/blender/io/collada/BCAnimationSampler.cpp b/source/blender/io/collada/BCAnimationSampler.cpp
index a6ee0b8bee6..b2a9027380e 100644
--- a/source/blender/io/collada/BCAnimationSampler.cpp
+++ b/source/blender/io/collada/BCAnimationSampler.cpp
@@ -536,7 +536,7 @@ const BCMatrix *BCSampleFrame::get_sample_matrix(Object *ob) const
return &sample->get_matrix();
}
-/* Get the matrix for the given Bone, returns Unity when the Objewct is not sampled */
+/* Get the matrix for the given Bone, returns Unity when the Object is not sampled. */
const BCMatrix *BCSampleFrame::get_sample_matrix(Object *ob, Bone *bone) const
{
BCSampleMap::const_iterator it = sampleMap.find(ob);
diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp
index 10c1a90576c..259bf901091 100644
--- a/source/blender/io/collada/DocumentImporter.cpp
+++ b/source/blender/io/collada/DocumentImporter.cpp
@@ -275,15 +275,15 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node,
COLLADAFW::Node *par = nullptr,
Object *parob = nullptr)
{
- /* The split in T29246, rootmap must point at actual root when
+ /* The split in T29246, root_map must point at actual root when
* calculating bones in apply_curves_as_matrix. - actual root is the root node.
* This has to do with inverse bind poses being world space
- * (the sources for skinned bones' restposes) and the way
- * non-skinning nodes have their "restpose" recursively calculated.
+ * (the sources for skinned bones' rest-poses) and the way
+ * non-skinning nodes have their "rest-pose" recursively calculated.
* XXX TODO: design issue, how to support unrelated joints taking
* part in skinning. */
if (par) { // && par->getType() == COLLADAFW::Node::JOINT) {
- /* par is root if there's no corresp. key in root_map */
+ /* If par is root if there's no corresponding key in root_map. */
if (root_map.find(par->getUniqueId()) == root_map.end()) {
root_map[node->getUniqueId()] = node;
}
@@ -942,7 +942,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
case CAM_PERSP:
default: {
double x = camera->getXFov().getValue();
- /* x is in degrees, cam->lens is in millimiters */
+ /* X is in degrees, cam->lens is in millimeters. */
cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x);
} break;
}
@@ -955,7 +955,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
case CAM_PERSP:
default: {
double yfov = camera->getYFov().getValue();
- /* yfov is in degrees, cam->lens is in millimiters */
+ /* yfov is in degrees, cam->lens is in millimeters. */
cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x);
} break;
}
diff --git a/source/blender/io/collada/DocumentImporter.h b/source/blender/io/collada/DocumentImporter.h
index a23e983940e..a6ed014a33c 100644
--- a/source/blender/io/collada/DocumentImporter.h
+++ b/source/blender/io/collada/DocumentImporter.h
@@ -125,7 +125,7 @@ class DocumentImporter : COLLADAFW::IWriter {
/** Add element and data for UniqueId */
bool addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags);
- /** Get an extisting ExtraTags for uid */
+ /** Get an existing #ExtraTags for uid */
ExtraTags *getExtraTags(const COLLADAFW::UniqueId &uid);
bool is_armature(COLLADAFW::Node *node);
diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp
index 2934ea1caa6..172f9a468b4 100644
--- a/source/blender/io/collada/MeshImporter.cpp
+++ b/source/blender/io/collada/MeshImporter.cpp
@@ -693,7 +693,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
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 vertces normals */
+ /* The same for vertices normals. */
unsigned int vertex_normal_indices[3] = {
first_normal, normal_indices[1], normal_indices[2]};
if (!is_flat_face(vertex_normal_indices, nor, 3)) {
diff --git a/source/blender/io/common/IO_dupli_persistent_id.hh b/source/blender/io/common/IO_dupli_persistent_id.hh
index 6fabafd9d51..afc539636ac 100644
--- a/source/blender/io/common/IO_dupli_persistent_id.hh
+++ b/source/blender/io/common/IO_dupli_persistent_id.hh
@@ -41,7 +41,7 @@ class PersistentID {
PersistentID();
explicit PersistentID(const DupliObject *dupli_ob);
- /* Return true iff the persistent IDs are the same, ignoring the first digit. */
+ /* Return true if the persistent IDs are the same, ignoring the first digit. */
bool is_from_same_instancer_as(const PersistentID &other) const;
/* Construct the persistent ID of this instance's instancer. */
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
index eaa4d2fdde7..a33d636500f 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
@@ -400,7 +400,7 @@ static bool remove_weak_subtrees(const HierarchyContext *context,
void AbstractHierarchyIterator::export_graph_prune()
{
- /* Take a copy of the map so that we can modify while recursing. */
+ /* Take a copy of the map so that we can modify while recusing. */
ExportGraph unpruned_export_graph = export_graph_;
remove_weak_subtrees(HierarchyContext::root(), export_graph_, unpruned_export_graph);
}
diff --git a/source/blender/io/common/intern/object_identifier_test.cc b/source/blender/io/common/intern/object_identifier_test.cc
index 30e1e43d076..8d0800ce2cb 100644
--- a/source/blender/io/common/intern/object_identifier_test.cc
+++ b/source/blender/io/common/intern/object_identifier_test.cc
@@ -129,7 +129,7 @@ TEST_F(ObjectIdentifierOrderTest, duplicated_objects)
EXPECT_FALSE(id_different_dupli_b < id_dupli_b);
}
-TEST_F(ObjectIdentifierOrderTest, behaviour_as_map_keys)
+TEST_F(ObjectIdentifierOrderTest, behavior_as_map_keys)
{
ObjectIdentifier id_root = ObjectIdentifier::for_graph_root();
ObjectIdentifier id_another_root = ObjectIdentifier::for_graph_root();
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 79b15c60b94..6ea30f48a13 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -30,6 +30,9 @@ if(WIN32)
endif()
add_definitions(-DPXR_STATIC)
+# USD headers use deprecated TBB headers, silence warning.
+add_definitions(-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1)
+
set(INC
.
../common
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 263ce2203e9..00d0d4e3626 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -24,6 +24,7 @@
#pragma once
+#include "DNA_ID_enums.h"
#include "DNA_defs.h"
#include "DNA_listBase.h"
@@ -193,6 +194,10 @@ enum {
IDOVERRIDE_LIBRARY_FLAG_MANDATORY = 1 << 0,
/** User cannot change that override operation. */
IDOVERRIDE_LIBRARY_FLAG_LOCKED = 1 << 1,
+
+ /** For overrides of ID pointers: this override still matches (follows) the hierarchy of the
+ * reference linked data. */
+ IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE = 1 << 8,
};
/** A single overridden property, contain all operations on this one. */
@@ -254,7 +259,7 @@ typedef struct IDOverrideLibrary {
/**
* ID is the first thing included in all serializable types. It
* provides a common handle to place all data in double-linked lists.
- * */
+ */
/* 2 characters for ID code and 64 for actual name */
#define MAX_ID_NAME 66
@@ -363,13 +368,6 @@ typedef struct Library {
short versionfile, subversionfile;
} Library;
-enum eIconSizes {
- ICON_SIZE_ICON = 0,
- ICON_SIZE_PREVIEW = 1,
-
- NUM_ICON_SIZES,
-};
-
/* for PreviewImage->flag */
enum ePreviewImage_Flag {
PRV_CHANGED = (1 << 0),
@@ -407,87 +405,6 @@ typedef struct PreviewImage {
BLI_assert((prv)->tag & PRV_TAG_DEFFERED), \
(void *)((prv) + 1))
-/**
- * Defines for working with IDs.
- *
- * The tags represent types! This is a dirty way of enabling RTTI. The
- * sig_byte end endian defines aren't really used much.
- */
-
-#ifdef __BIG_ENDIAN__
-/* big endian */
-# define MAKE_ID2(c, d) ((c) << 8 | (d))
-#else
-/* little endian */
-# define MAKE_ID2(c, d) ((d) << 8 | (c))
-#endif
-
-/**
- * ID from database.
- *
- * Written to #BHead.code (for file IO)
- * and the first 2 bytes of #ID.name (for runtime checks, see #GS macro).
- */
-typedef enum ID_Type {
- ID_SCE = MAKE_ID2('S', 'C'), /* Scene */
- ID_LI = MAKE_ID2('L', 'I'), /* Library */
- ID_OB = MAKE_ID2('O', 'B'), /* Object */
- ID_ME = MAKE_ID2('M', 'E'), /* Mesh */
- ID_CU = MAKE_ID2('C', 'U'), /* Curve */
- ID_MB = MAKE_ID2('M', 'B'), /* MetaBall */
- ID_MA = MAKE_ID2('M', 'A'), /* Material */
- ID_TE = MAKE_ID2('T', 'E'), /* Tex (Texture) */
- ID_IM = MAKE_ID2('I', 'M'), /* Image */
- ID_LT = MAKE_ID2('L', 'T'), /* Lattice */
- ID_LA = MAKE_ID2('L', 'A'), /* Light */
- ID_CA = MAKE_ID2('C', 'A'), /* Camera */
- ID_IP = MAKE_ID2('I', 'P'), /* Ipo (depreciated, replaced by FCurves) */
- ID_KE = MAKE_ID2('K', 'E'), /* Key (shape key) */
- ID_WO = MAKE_ID2('W', 'O'), /* World */
- ID_SCR = MAKE_ID2('S', 'R'), /* Screen */
- ID_VF = MAKE_ID2('V', 'F'), /* VFont (Vector Font) */
- ID_TXT = MAKE_ID2('T', 'X'), /* Text */
- ID_SPK = MAKE_ID2('S', 'K'), /* Speaker */
- ID_SO = MAKE_ID2('S', 'O'), /* Sound */
- ID_GR = MAKE_ID2('G', 'R'), /* Group */
- ID_AR = MAKE_ID2('A', 'R'), /* bArmature */
- ID_AC = MAKE_ID2('A', 'C'), /* bAction */
- ID_NT = MAKE_ID2('N', 'T'), /* bNodeTree */
- ID_BR = MAKE_ID2('B', 'R'), /* Brush */
- ID_PA = MAKE_ID2('P', 'A'), /* ParticleSettings */
- ID_GD = MAKE_ID2('G', 'D'), /* bGPdata, (Grease Pencil) */
- ID_WM = MAKE_ID2('W', 'M'), /* WindowManager */
- ID_MC = MAKE_ID2('M', 'C'), /* MovieClip */
- ID_MSK = MAKE_ID2('M', 'S'), /* Mask */
- ID_LS = MAKE_ID2('L', 'S'), /* FreestyleLineStyle */
- ID_PAL = MAKE_ID2('P', 'L'), /* Palette */
- ID_PC = MAKE_ID2('P', 'C'), /* PaintCurve */
- ID_CF = MAKE_ID2('C', 'F'), /* CacheFile */
- ID_WS = MAKE_ID2('W', 'S'), /* WorkSpace */
- ID_LP = MAKE_ID2('L', 'P'), /* LightProbe */
- ID_HA = MAKE_ID2('H', 'A'), /* Hair */
- ID_PT = MAKE_ID2('P', 'T'), /* PointCloud */
- ID_VO = MAKE_ID2('V', 'O'), /* Volume */
- ID_SIM = MAKE_ID2('S', 'I'), /* Simulation (currently unused) */
-} ID_Type;
-
-/* Only used as 'placeholder' in .blend files for directly linked data-blocks. */
-#define ID_LINK_PLACEHOLDER MAKE_ID2('I', 'D') /* (internal use only) */
-
-/* Deprecated. */
-#define ID_SCRN MAKE_ID2('S', 'N')
-
-/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
-#define ID_SEQ MAKE_ID2('S', 'Q')
-/* constraint */
-#define ID_CO MAKE_ID2('C', 'O')
-/* pose (action channel, used to be ID_AC in code, so we keep code for backwards compat) */
-#define ID_PO MAKE_ID2('A', 'C')
-/* used in outliner... */
-#define ID_NLA MAKE_ID2('N', 'L')
-/* fluidsim Ipo */
-#define ID_FLUIDSIM MAKE_ID2('F', 'S')
-
#define ID_FAKE_USERS(id) ((((const ID *)id)->flag & LIB_FAKEUSER) ? 1 : 0)
#define ID_REAL_USERS(id) (((const ID *)id)->us - ID_FAKE_USERS(id))
#define ID_EXTRA_USERS(id) (((const ID *)id)->tag & LIB_TAG_EXTRAUSER ? 1 : 0)
@@ -510,6 +427,10 @@ typedef enum ID_Type {
(ID_IS_LINKED(_id) && !ID_MISSING(_id) && (((const ID *)(_id))->tag & LIB_TAG_EXTERN) != 0 && \
(BKE_idtype_get_info_from_id((const ID *)(_id))->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0)
+/* NOTE: The three checks below do not take into account whether given ID is linked or not (when
+ * chaining overrides over several libraries). User must ensure the ID is not linked itself
+ * currently. */
+/* TODO: add `_EDITABLE` versions of those macros (that would check if ID is linked or not)? */
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id) \
(((const ID *)(_id))->override_library != NULL && \
((const ID *)(_id))->override_library->reference != NULL)
@@ -685,7 +606,7 @@ typedef enum IDRecalcFlag {
* redraw update in that case. */
/* Selection of the ID itself or its components (for example, vertices) did
- * change, and all the drawing data is to eb updated. */
+ * change, and all the drawing data is to be updated. */
ID_RECALC_SELECT = (1 << 9),
/* Flags on the base did change, and is to be copied onto all the copies of
* corresponding objects. */
diff --git a/source/blender/makesdna/DNA_ID_enums.h b/source/blender/makesdna/DNA_ID_enums.h
new file mode 100644
index 00000000000..04cbf51dd62
--- /dev/null
+++ b/source/blender/makesdna/DNA_ID_enums.h
@@ -0,0 +1,118 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup DNA
+ * \brief Enumerations for `DNA_ID.h`.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum eIconSizes {
+ ICON_SIZE_ICON = 0,
+ ICON_SIZE_PREVIEW = 1,
+
+ NUM_ICON_SIZES,
+};
+
+/**
+ * Defines for working with IDs.
+ *
+ * The tags represent types! This is a dirty way of enabling RTTI. The
+ * sig_byte end endian defines aren't really used much.
+ */
+
+#ifdef __BIG_ENDIAN__
+/* big endian */
+# define MAKE_ID2(c, d) ((c) << 8 | (d))
+#else
+/* little endian */
+# define MAKE_ID2(c, d) ((d) << 8 | (c))
+#endif
+
+/**
+ * ID from database.
+ *
+ * Written to #BHead.code (for file IO)
+ * and the first 2 bytes of #ID.name (for runtime checks, see #GS macro).
+ */
+typedef enum ID_Type {
+ ID_SCE = MAKE_ID2('S', 'C'), /* Scene */
+ ID_LI = MAKE_ID2('L', 'I'), /* Library */
+ ID_OB = MAKE_ID2('O', 'B'), /* Object */
+ ID_ME = MAKE_ID2('M', 'E'), /* Mesh */
+ ID_CU = MAKE_ID2('C', 'U'), /* Curve */
+ ID_MB = MAKE_ID2('M', 'B'), /* MetaBall */
+ ID_MA = MAKE_ID2('M', 'A'), /* Material */
+ ID_TE = MAKE_ID2('T', 'E'), /* Tex (Texture) */
+ ID_IM = MAKE_ID2('I', 'M'), /* Image */
+ ID_LT = MAKE_ID2('L', 'T'), /* Lattice */
+ ID_LA = MAKE_ID2('L', 'A'), /* Light */
+ ID_CA = MAKE_ID2('C', 'A'), /* Camera */
+ ID_IP = MAKE_ID2('I', 'P'), /* Ipo (depreciated, replaced by FCurves) */
+ ID_KE = MAKE_ID2('K', 'E'), /* Key (shape key) */
+ ID_WO = MAKE_ID2('W', 'O'), /* World */
+ ID_SCR = MAKE_ID2('S', 'R'), /* Screen */
+ ID_VF = MAKE_ID2('V', 'F'), /* VFont (Vector Font) */
+ ID_TXT = MAKE_ID2('T', 'X'), /* Text */
+ ID_SPK = MAKE_ID2('S', 'K'), /* Speaker */
+ ID_SO = MAKE_ID2('S', 'O'), /* Sound */
+ ID_GR = MAKE_ID2('G', 'R'), /* Collection */
+ ID_AR = MAKE_ID2('A', 'R'), /* bArmature */
+ ID_AC = MAKE_ID2('A', 'C'), /* bAction */
+ ID_NT = MAKE_ID2('N', 'T'), /* bNodeTree */
+ ID_BR = MAKE_ID2('B', 'R'), /* Brush */
+ ID_PA = MAKE_ID2('P', 'A'), /* ParticleSettings */
+ ID_GD = MAKE_ID2('G', 'D'), /* bGPdata, (Grease Pencil) */
+ ID_WM = MAKE_ID2('W', 'M'), /* WindowManager */
+ ID_MC = MAKE_ID2('M', 'C'), /* MovieClip */
+ ID_MSK = MAKE_ID2('M', 'S'), /* Mask */
+ ID_LS = MAKE_ID2('L', 'S'), /* FreestyleLineStyle */
+ ID_PAL = MAKE_ID2('P', 'L'), /* Palette */
+ ID_PC = MAKE_ID2('P', 'C'), /* PaintCurve */
+ ID_CF = MAKE_ID2('C', 'F'), /* CacheFile */
+ ID_WS = MAKE_ID2('W', 'S'), /* WorkSpace */
+ ID_LP = MAKE_ID2('L', 'P'), /* LightProbe */
+ ID_HA = MAKE_ID2('H', 'A'), /* Hair */
+ ID_PT = MAKE_ID2('P', 'T'), /* PointCloud */
+ ID_VO = MAKE_ID2('V', 'O'), /* Volume */
+ ID_SIM = MAKE_ID2('S', 'I'), /* Simulation (geometry node groups) */
+} ID_Type;
+
+/* Only used as 'placeholder' in .blend files for directly linked data-blocks. */
+#define ID_LINK_PLACEHOLDER MAKE_ID2('I', 'D') /* (internal use only) */
+
+/* Deprecated. */
+#define ID_SCRN MAKE_ID2('S', 'N')
+
+/* NOTE: Fake IDs, needed for `g.sipo->blocktype` or outliner. */
+#define ID_SEQ MAKE_ID2('S', 'Q')
+/* constraint */
+#define ID_CO MAKE_ID2('C', 'O')
+/* pose (action channel, used to be ID_AC in code, so we keep code for backwards compatible). */
+#define ID_PO MAKE_ID2('A', 'C')
+/* used in outliner... */
+#define ID_NLA MAKE_ID2('N', 'L')
+/* fluidsim Ipo */
+#define ID_FLUIDSIM MAKE_ID2('F', 'S')
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 790a7a36288..96245e3b067 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -676,6 +676,8 @@ typedef struct bAction {
*/
int idroot;
char _pad[4];
+
+ PreviewImage *preview;
} bAction;
/* Flags for the action */
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 1eafa655195..c66618c0acd 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -438,9 +438,10 @@ typedef enum eDriverVar_Types {
/** 'final' transform for object/bones */
DVAR_TYPE_TRANSFORM_CHAN,
- /** Maximum number of variable types.
+ /**
+ * Maximum number of variable types.
*
- * \note This must always be th last item in this list,
+ * \note This must always be the last item in this list,
* so add new types above this line.
*/
MAX_DVAR_TYPES,
diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h
index f12934c9104..093a1a00ece 100644
--- a/source/blender/makesdna/DNA_brush_enums.h
+++ b/source/blender/makesdna/DNA_brush_enums.h
@@ -75,6 +75,10 @@ typedef enum eGPDbrush_Flag {
GP_BRUSH_USE_STRENGTH_PRESSURE = (1 << 1),
/* brush use pressure for alpha factor */
GP_BRUSH_USE_JITTER_PRESSURE = (1 << 2),
+ /* Disable automatic zoom for filling. */
+ GP_BRUSH_FILL_FIT_DISABLE = (1 << 3),
+ /* Show extend fill help lines. */
+ GP_BRUSH_FILL_SHOW_EXTENDLINES = (1 << 4),
/* fill hide transparent */
GP_BRUSH_FILL_HIDE = (1 << 6),
/* show fill help lines */
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 4b020019062..a11e7d77c67 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -50,7 +50,8 @@ typedef struct BrushClone {
typedef struct BrushGpencilSettings {
/** Amount of smoothing to apply to newly created strokes. */
float draw_smoothfac;
- char _pad2[4];
+ /** Fill zoom factor */
+ float fill_factor;
/** Amount of alpha strength to apply to newly created strokes. */
float draw_strength;
/** Amount of jitter to apply to newly created strokes. */
@@ -75,8 +76,8 @@ typedef struct BrushGpencilSettings {
float fill_threshold;
/** Number of pixel to consider the leak is too small (x 2). */
short fill_leak;
- /** Fill zoom factor */
- short fill_factor;
+ char _pad2[2];
+
int flag2;
/** Number of simplify steps. */
@@ -130,6 +131,10 @@ typedef struct BrushGpencilSettings {
/** Randomness for Value. */
float random_value;
+ /** Factor to extend stroke extremes using fill tool. */
+ float fill_extend_fac;
+ char _pad3[4];
+
struct CurveMapping *curve_sensitivity;
struct CurveMapping *curve_strength;
struct CurveMapping *curve_jitter;
@@ -286,7 +291,7 @@ typedef struct Brush {
int curve_preset;
- /* Maximun distance to search fake neighbors from a vertex. */
+ /* Maximum distance to search fake neighbors from a vertex. */
float disconnected_distance_max;
int deform_target;
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 467174c4f32..1eff7be3f15 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -166,7 +166,7 @@ typedef struct ClothSimSettings {
/** Mechanical damping of shear springs. */
float shear_damp;
- /** The maximum lenght an internal spring can have during creation. */
+ /** The maximum length an internal spring can have during creation. */
float internal_spring_max_length;
/** How much the interal spring can diverge from the vertex normal during creation. */
float internal_spring_max_diversion;
diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h
index c8e09225432..e3dcd283efa 100644
--- a/source/blender/makesdna/DNA_dynamicpaint_types.h
+++ b/source/blender/makesdna/DNA_dynamicpaint_types.h
@@ -242,10 +242,12 @@ typedef struct DynamicPaintBrushSettings {
/** For fast RNA access. */
struct DynamicPaintModifierData *pmd;
- /* NOTE: Storing the particle system pointer here is very weak, as it prevents modfiers' data
+ /**
+ * \note Storing the particle system pointer here is very weak, as it prevents modifiers' data
* copying to be self-sufficient (extra external code needs to ensure the pointer remains valid
* when the modifier data is copied from one object to another). See e.g.
- * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`. */
+ * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`.
+ */
struct ParticleSystem *psys;
int flags;
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
index fdb77bfd196..399bf6f0a6d 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
@@ -152,6 +152,7 @@
.factor_thickness = 0.0f, \
.factor_uvs = 0.0f, \
.noise_scale = 0.0f, \
+ .noise_offset = 0.0f, \
.step = 4, \
.layer_pass = 0, \
.seed = 1, \
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index 9ac40495887..b2d62e0a5f6 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -107,6 +107,8 @@ typedef struct NoiseGpencilModifierData {
float factor_uvs;
/** Noise Frequency scaling */
float noise_scale;
+ float noise_offset;
+ char _pad[4];
/** How many frames before recalculate randoms. */
int step;
/** Custom index for passes. */
@@ -180,7 +182,7 @@ typedef struct ThickGpencilModifierData {
int flag;
/** Relative thickness factor. */
float thickness_fac;
- /** Absolute thickness overide. */
+ /** Absolute thickness override. */
int thickness;
/** Custom index for passes. */
int layer_pass;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 949b0bb5bf5..e02757c1249 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -45,6 +45,9 @@ struct MDeformVert;
#define GP_DEFAULT_CURVE_ERROR 0.1f
#define GP_DEFAULT_CURVE_EDIT_CORNER_ANGLE M_PI_2
+#define GPENCIL_MIN_FILL_FAC 0.05f
+#define GPENCIL_MAX_FILL_FAC 5.0f
+
/* ***************************************** */
/* GP Stroke Points */
@@ -512,6 +515,11 @@ typedef struct bGPDlayer {
int act_mask;
char _pad2[4];
+ /** Layer transforms. */
+ float location[3], rotation[3], scale[3];
+ float layer_mat[4][4], layer_invmat[4][4];
+ char _pad3[4];
+
bGPDlayer_Runtime runtime;
} bGPDlayer;
@@ -574,7 +582,9 @@ typedef struct bGPdata_Runtime {
/** Temp stroke used for drawing. */
struct bGPDstroke *sbuffer_gps;
- char _pad[2];
+ /** Animation playing flag. */
+ short playing;
+
/** Material index of the stroke. */
short matid;
@@ -802,8 +812,9 @@ typedef enum eGP_DrawMode {
/* Check if 'multiedit sessions' is enabled */
#define GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) \
((gpd) && \
- ((gpd)->flag & (GP_DATA_STROKE_EDITMODE | GP_DATA_STROKE_SCULPTMODE | \
- GP_DATA_STROKE_WEIGHTMODE | GP_DATA_STROKE_VERTEXMODE)) && \
+ ((gpd)->flag & \
+ (GP_DATA_STROKE_PAINTMODE | GP_DATA_STROKE_EDITMODE | GP_DATA_STROKE_SCULPTMODE | \
+ GP_DATA_STROKE_WEIGHTMODE | GP_DATA_STROKE_VERTEXMODE)) && \
((gpd)->flag & GP_DATA_STROKE_MULTIEDIT))
#define GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd) \
@@ -840,6 +851,8 @@ typedef enum eGP_DrawMode {
((flag & (GP_VERTEX_MASK_SELECTMODE_POINT | GP_VERTEX_MASK_SELECTMODE_STROKE | \
GP_VERTEX_MASK_SELECTMODE_SEGMENT)))
+#define GPENCIL_PLAY_ON(gpd) ((gpd) && ((gpd)->runtime.playing == 1))
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 780115a31be..05be31262a6 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -271,6 +271,9 @@ typedef struct MIntProperty {
typedef struct MStringProperty {
char s[255], s_len;
} MStringProperty;
+typedef struct MBoolProperty {
+ uint8_t b;
+} MBoolProperty;
/** \} */
@@ -414,7 +417,6 @@ typedef struct OrigSpaceLoop {
typedef struct FreestyleEdge {
char flag;
- char _pad[3];
} FreestyleEdge;
/** #FreestyleEdge.flag */
@@ -424,7 +426,6 @@ enum {
typedef struct FreestyleFace {
char flag;
- char _pad[3];
} FreestyleFace;
/** #FreestyleFace.flag */
diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h
index 8601dcf76ac..9335c360363 100644
--- a/source/blender/makesdna/DNA_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_modifier_defaults.h
@@ -236,7 +236,7 @@
.flag = 0, \
}
-/* Defines are scattered accross too many files, they need to be moved to DNA. */
+/* Defines are scattered across too many files, they need to be moved to DNA. */
#if 0
#define _DNA_DEFAULT_DataTransferModifierData \
{ \
@@ -440,7 +440,7 @@
.renderlvl = 0, \
.totlvl = 0, \
.flags = eMultiresModifierFlag_UseCrease | eMultiresModifierFlag_ControlEdges, \
- .uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS, \
+ .uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES, \
.quality = 4, \
.boundary_smooth = SUBSURF_BOUNDARY_SMOOTH_ALL, \
}
@@ -622,7 +622,7 @@
.levels = 1, \
.renderLevels = 2, \
.flags = eSubsurfModifierFlag_UseCrease | eSubsurfModifierFlag_ControlEdges, \
- .uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS, \
+ .uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES, \
.quality = 3, \
.boundary_smooth = SUBSURF_BOUNDARY_SMOOTH_ALL, \
.emCache = NULL, \
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 3de4299e0bd..29421430e5d 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -984,10 +984,12 @@ enum {
typedef struct ParticleSystemModifierData {
ModifierData modifier;
- /* NOTE: Storing the particle system pointer here is very weak, as it prevents modfiers' data
+ /**
+ * \note Storing the particle system pointer here is very weak, as it prevents modifiers' data
* copying to be self-sufficient (extra external code needs to ensure the pointer remains valid
* when the modifier data is copied from one object to another). See e.g.
- * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`. */
+ * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`.
+ */
struct ParticleSystem *psys;
/** Final Mesh - its topology may differ from orig mesh. */
struct Mesh *mesh_final;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 7d18ff3ed58..43c5fa81651 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -118,7 +118,9 @@ typedef struct bNodeSocket {
/* XXX deprecated, kept for forward compatibility */
short stack_type DNA_DEPRECATED;
char display_shape;
- char _pad[3];
+ char _pad[1];
+ /* Runtime-only cache of the number of input links, for multi-input sockets. */
+ short total_inputs;
/** Custom dynamic defined label, MAX_NAME. */
char label[64];
@@ -200,6 +202,8 @@ typedef enum eNodeSocketFlag {
SOCK_NO_INTERNAL_LINK = (1 << 9),
/** Draw socket in a more compact form. */
SOCK_COMPACT = (1 << 10),
+ /** Make the input socket accept multiple incoming links in the UI. */
+ SOCK_MULTI_INPUT = (1 << 11),
} eNodeSocketFlag;
/* limit data in bNode to what we want to see saved? */
@@ -389,13 +393,15 @@ typedef struct bNodeLink {
bNodeSocket *fromsock, *tosock;
int flag;
- char _pad[4];
+ /* A runtime storage for automatically sorted links to multi-input sockets. */
+ int multi_input_socket_index;
} bNodeLink;
/* link->flag */
#define NODE_LINKFLAG_HILITE (1 << 0) /* link has been successfully validated */
#define NODE_LINK_VALID (1 << 1)
-#define NODE_LINK_TEST (1 << 2) /* free test flag, undefined */
+#define NODE_LINK_TEST (1 << 2) /* free test flag, undefined */
+#define NODE_LINK_TEMP_HIGHLIGHT (1 << 3) /* Link is highlighted for picking. */
/* tree->edit_quality/tree->render_quality */
#define NTREE_QUALITY_HIGH 0
@@ -549,7 +555,6 @@ typedef struct bNodeSocketValueFloat {
typedef struct bNodeSocketValueBoolean {
char value;
- char _pad[3];
} bNodeSocketValueBoolean;
typedef struct bNodeSocketValueVector {
@@ -829,7 +834,6 @@ typedef struct NodeColorspill {
typedef struct NodeDilateErode {
char falloff;
- char _pad[7];
} NodeDilateErode;
typedef struct NodeMask {
@@ -838,7 +842,6 @@ typedef struct NodeMask {
typedef struct NodeSetAlpha {
char mode;
- char _pad[7];
} NodeSetAlpha;
typedef struct NodeTexBase {
@@ -995,7 +998,6 @@ typedef struct NodeTrackPosData {
typedef struct NodeTranslateData {
char wrap_axis;
char relative;
- char _pad[6];
} NodeTranslateData;
typedef struct NodePlaneTrackDeformData {
@@ -1074,7 +1076,6 @@ typedef struct NodeCryptomatte {
typedef struct NodeDenoise {
char hdr;
- char _pad[7];
} NodeDenoise;
typedef struct NodeAttributeCompare {
@@ -1089,14 +1090,13 @@ typedef struct NodeAttributeCompare {
} NodeAttributeCompare;
typedef struct NodeAttributeMath {
- /* e.g. NODE_MATH_ADD. */
+ /* NodeMathOperation. */
uint8_t operation;
/* GeometryNodeAttributeInputMode */
uint8_t input_type_a;
uint8_t input_type_b;
-
- char _pad[5];
+ uint8_t input_type_c;
} NodeAttributeMath;
typedef struct NodeAttributeMix {
@@ -1117,8 +1117,6 @@ typedef struct NodeAttributeVectorMath {
uint8_t input_type_a;
uint8_t input_type_b;
uint8_t input_type_c;
-
- char _pad[4];
} NodeAttributeVectorMath;
typedef struct NodeAttributeColorRamp {
@@ -1145,35 +1143,72 @@ typedef struct NodeGeometryRotatePoints {
typedef struct NodeGeometryAlignRotationToVector {
/* GeometryNodeAlignRotationToVectorAxis */
uint8_t axis;
+ /* GeometryNodeAlignRotationToVectorPivotAxis */
+ uint8_t pivot_axis;
/* GeometryNodeAttributeInputMode */
uint8_t input_type_factor;
uint8_t input_type_vector;
-
- char _pad[5];
} NodeGeometryAlignRotationToVector;
typedef struct NodeGeometryPointScale {
/* GeometryNodeAttributeInputMode */
uint8_t input_type;
-
- char _pad[7];
} NodeGeometryPointScale;
typedef struct NodeGeometryPointTranslate {
/* GeometryNodeAttributeInputMode */
uint8_t input_type;
-
- char _pad[7];
} NodeGeometryPointTranslate;
typedef struct NodeGeometryObjectInfo {
/* GeometryNodeTransformSpace. */
uint8_t transform_space;
-
- char _pad[7];
} NodeGeometryObjectInfo;
+typedef struct NodeGeometryPointInstance {
+ /* GeometryNodePointInstanceType. */
+ uint8_t instance_type;
+ /* GeometryNodePointInstanceFlag. */
+ uint8_t flag;
+} NodeGeometryPointInstance;
+
+typedef struct NodeGeometryPointsToVolume {
+ /* GeometryNodePointsToVolumeResolutionMode */
+ uint8_t resolution_mode;
+ /* GeometryNodeAttributeInputMode */
+ uint8_t input_type_radius;
+} NodeGeometryPointsToVolume;
+
+typedef struct NodeGeometryCollectionInfo {
+ /* GeometryNodeTransformSpace. */
+ uint8_t transform_space;
+} NodeGeometryCollectionInfo;
+
+typedef struct NodeGeometryAttributeProximity {
+ /* GeometryNodeAttributeProximityTargetGeometryElement. */
+ uint8_t target_geometry_element;
+} NodeGeometryAttributeProximity;
+
+typedef struct NodeGeometryVolumeToMesh {
+ /* VolumeToMeshResolutionMode */
+ uint8_t resolution_mode;
+} NodeGeometryVolumeToMesh;
+
+typedef struct NodeAttributeCombineXYZ {
+ /* GeometryNodeAttributeInputMode. */
+ uint8_t input_type_x;
+ uint8_t input_type_y;
+ uint8_t input_type_z;
+
+ char _pad[1];
+} NodeAttributeCombineXYZ;
+
+typedef struct NodeAttributeSeparateXYZ {
+ /* GeometryNodeAttributeInputMode. */
+ uint8_t input_type;
+} NodeAttributeSeparateXYZ;
+
/* script node mode */
#define NODE_SCRIPT_INTERNAL 0
#define NODE_SCRIPT_EXTERNAL 1
@@ -1369,7 +1404,7 @@ enum {
#define SHD_MATH_CLAMP 1
/* Math node operations. */
-enum {
+typedef enum NodeMathOperation {
NODE_MATH_ADD = 0,
NODE_MATH_SUBTRACT = 1,
NODE_MATH_MULTIPLY = 2,
@@ -1410,7 +1445,7 @@ enum {
NODE_MATH_PINGPONG = 37,
NODE_MATH_SMOOTH_MIN = 38,
NODE_MATH_SMOOTH_MAX = 39,
-};
+} NodeMathOperation;
/* Vector Math node operations. */
typedef enum NodeVectorMathOperation {
@@ -1561,6 +1596,12 @@ typedef enum NodeShaderOutputTarget {
/* Geometry Nodes */
+typedef enum GeometryNodeAttributeProximityTargetGeometryElement {
+ GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_POINTS = 0,
+ GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_EDGES = 1,
+ GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_FACES = 2,
+} GeometryNodeAttributeProximityTargetGeometryElement;
+
/* Boolean Node */
typedef enum GeometryNodeBooleanOperation {
GEO_NODE_BOOLEAN_INTERSECT = 0,
@@ -1586,6 +1627,10 @@ typedef enum GeometryNodePointInstanceType {
GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION = 1,
} GeometryNodePointInstanceType;
+typedef enum GeometryNodePointInstanceFlag {
+ GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION = (1 << 0),
+} GeometryNodePointInstanceFlag;
+
typedef enum GeometryNodeAttributeInputMode {
GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE = 0,
GEO_NODE_ATTRIBUTE_INPUT_FLOAT = 1,
@@ -1615,11 +1660,23 @@ typedef enum GeometryNodeAlignRotationToVectorAxis {
GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_Z = 2,
} GeometryNodeAlignRotationToVectorAxis;
+typedef enum GeometryNodeAlignRotationToVectorPivotAxis {
+ GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_AUTO = 0,
+ GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_X = 1,
+ GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_Y = 2,
+ GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_Z = 3,
+} GeometryNodeAlignRotationToVectorPivotAxis;
+
typedef enum GeometryNodeTransformSpace {
GEO_NODE_TRANSFORM_SPACE_ORIGINAL = 0,
GEO_NODE_TRANSFORM_SPACE_RELATIVE = 1,
} GeometryNodeTransformSpace;
+typedef enum GeometryNodePointsToVolumeResolutionMode {
+ GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT = 0,
+ GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE = 1,
+} GeometryNodePointsToVolumeResolutionMode;
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h
index 8a8a40a5069..16129768b60 100644
--- a/source/blender/makesdna/DNA_outliner_types.h
+++ b/source/blender/makesdna/DNA_outliner_types.h
@@ -72,53 +72,55 @@ enum {
};
/** #TreeStoreElem.types */
-#define TSE_NLA 1 /* NO ID */
-#define TSE_NLA_ACTION 2
-#define TSE_DEFGROUP_BASE 3
-#define TSE_DEFGROUP 4
-#define TSE_BONE 5
-#define TSE_EBONE 6
-#define TSE_CONSTRAINT_BASE 7
-#define TSE_CONSTRAINT 8
-#define TSE_MODIFIER_BASE 9
-#define TSE_MODIFIER 10
-#define TSE_LINKED_OB 11
-/* #define TSE_SCRIPT_BASE 12 */ /* UNUSED */
-#define TSE_POSE_BASE 13
-#define TSE_POSE_CHANNEL 14
-#define TSE_ANIM_DATA 15
-#define TSE_DRIVER_BASE 16 /* NO ID */
-/* #define TSE_DRIVER 17 */ /* UNUSED */
+typedef enum eTreeStoreElemType {
+ TSE_NLA = 1, /* NO ID */
+ TSE_NLA_ACTION = 2,
+ TSE_DEFGROUP_BASE = 3,
+ TSE_DEFGROUP = 4,
+ TSE_BONE = 5,
+ TSE_EBONE = 6,
+ TSE_CONSTRAINT_BASE = 7,
+ TSE_CONSTRAINT = 8,
+ TSE_MODIFIER_BASE = 9,
+ TSE_MODIFIER = 10,
+ TSE_LINKED_OB = 11,
+ /* TSE_SCRIPT_BASE = 12, */ /* UNUSED */
+ TSE_POSE_BASE = 13,
+ TSE_POSE_CHANNEL = 14,
+ TSE_ANIM_DATA = 15,
+ TSE_DRIVER_BASE = 16, /* NO ID */
+ /* TSE_DRIVER = 17, */ /* UNUSED */
-#define TSE_PROXY 18
-#define TSE_R_LAYER_BASE 19
-#define TSE_R_LAYER 20
-/* #define TSE_R_PASS 21 */ /* UNUSED */
-#define TSE_LINKED_MAT 22
-/* NOTE, is used for light group */
-#define TSE_LINKED_LAMP 23
-#define TSE_POSEGRP_BASE 24
-#define TSE_POSEGRP 25
-#define TSE_SEQUENCE 26 /* NO ID */
-#define TSE_SEQ_STRIP 27 /* NO ID */
-#define TSE_SEQUENCE_DUP 28 /* NO ID */
-#define TSE_LINKED_PSYS 29
-#define TSE_RNA_STRUCT 30 /* NO ID */
-#define TSE_RNA_PROPERTY 31 /* NO ID */
-#define TSE_RNA_ARRAY_ELEM 32 /* NO ID */
-#define TSE_NLA_TRACK 33 /* NO ID */
-#define TSE_KEYMAP 34 /* NO ID */
-#define TSE_KEYMAP_ITEM 35 /* NO ID */
-#define TSE_ID_BASE 36 /* NO ID */
-#define TSE_GP_LAYER 37 /* NO ID */
-#define TSE_LAYER_COLLECTION 38
-#define TSE_SCENE_COLLECTION_BASE 39
-#define TSE_VIEW_COLLECTION_BASE 40
-#define TSE_SCENE_OBJECTS_BASE 41
-#define TSE_GPENCIL_EFFECT_BASE 42
-#define TSE_GPENCIL_EFFECT 43
-#define TSE_LIBRARY_OVERRIDE_BASE 44
-#define TSE_LIBRARY_OVERRIDE 45
+ TSE_PROXY = 18,
+ TSE_R_LAYER_BASE = 19,
+ TSE_R_LAYER = 20,
+ /* TSE_R_PASS = 21, */ /* UNUSED */
+ /* TSE_LINKED_MAT = 22, */
+ /* NOTE, is used for light group */
+ /* TSE_LINKED_LAMP = 23, */
+ TSE_POSEGRP_BASE = 24,
+ TSE_POSEGRP = 25,
+ TSE_SEQUENCE = 26, /* NO ID */
+ TSE_SEQ_STRIP = 27, /* NO ID */
+ TSE_SEQUENCE_DUP = 28, /* NO ID */
+ TSE_LINKED_PSYS = 29,
+ TSE_RNA_STRUCT = 30, /* NO ID */
+ TSE_RNA_PROPERTY = 31, /* NO ID */
+ TSE_RNA_ARRAY_ELEM = 32, /* NO ID */
+ TSE_NLA_TRACK = 33, /* NO ID */
+ /* TSE_KEYMAP = 34, */ /* UNUSED */
+ /* TSE_KEYMAP_ITEM = 35, */ /* UNUSED */
+ TSE_ID_BASE = 36, /* NO ID */
+ TSE_GP_LAYER = 37, /* NO ID */
+ TSE_LAYER_COLLECTION = 38,
+ TSE_SCENE_COLLECTION_BASE = 39,
+ TSE_VIEW_COLLECTION_BASE = 40,
+ TSE_SCENE_OBJECTS_BASE = 41,
+ TSE_GPENCIL_EFFECT_BASE = 42,
+ TSE_GPENCIL_EFFECT = 43,
+ TSE_LIBRARY_OVERRIDE_BASE = 44,
+ TSE_LIBRARY_OVERRIDE = 45,
+} eTreeStoreElemType;
/** Check whether given #TreeStoreElem should have a real ID in #TreeStoreElem.id member. */
#define TSE_IS_REAL_ID(_tse) \
@@ -132,8 +134,6 @@ enum {
TSE_RNA_STRUCT, \
TSE_RNA_PROPERTY, \
TSE_RNA_ARRAY_ELEM, \
- TSE_KEYMAP, \
- TSE_KEYMAP_ITEM, \
TSE_ID_BASE, \
TSE_GP_LAYER))
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 03f5d3f8d47..51f8b58da62 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -63,6 +63,9 @@ struct wmTimer;
/* Defined in `buttons_intern.h`. */
typedef struct SpaceProperties_Runtime SpaceProperties_Runtime;
+/* Defined in `node_intern.h`. */
+typedef struct SpaceNode_Runtime SpaceNode_Runtime;
+
/* -------------------------------------------------------------------- */
/** \name SpaceLink (Base)
* \{ */
@@ -1084,6 +1087,8 @@ typedef struct FileDirEntry {
struct FileDirEntry *next, *prev;
int uuid[4];
+ /* Name needs freeing if FILE_ENTRY_NAME_FREE is set. Otherwise this is a direct pointer to a
+ * name buffer. */
char *name;
char *description;
@@ -1162,6 +1167,7 @@ enum {
/* FileDirEntry.flags */
enum {
FILE_ENTRY_INVALID_PREVIEW = 1 << 0, /* The preview for this entry could not be generated. */
+ FILE_ENTRY_NAME_FREE = 1 << 1,
};
/** \} */
@@ -1518,19 +1524,17 @@ typedef struct SpaceNode {
/** Context, no need to save in file? well... pinning... */
struct ID *id, *from;
- /** Menunr: browse id block in header. */
+
short flag;
- char _pad1[2];
- /** Internal state variables. */
- float aspect;
- char _pad2[4];
+
+ /** Direction for offsetting nodes on insertion. */
+ char insert_ofs_dir;
+ char _pad1;
/** Offset for drawing the backdrop. */
float xof, yof;
/** Zoom for backdrop. */
float zoom;
- /** Mouse pos for drawing socketless link and adding nodes. */
- float cursor[2];
/**
* XXX nodetree pointer info is all in the path stack now,
@@ -1541,33 +1545,25 @@ typedef struct SpaceNode {
*/
ListBase treepath;
- struct bNodeTree *nodetree, *edittree;
+ /* The tree farthest down in the group heirarchy. */
+ struct bNodeTree *edittree;
+
+ struct bNodeTree *nodetree;
/* tree type for the current node tree */
char tree_idname[64];
/** Treetype: as same nodetree->type. */
int treetype DNA_DEPRECATED;
- char _pad3[4];
/** Texfrom object, world or brush. */
short texfrom;
/** Shader from object or world. */
short shaderfrom;
- /** Currently on 0/1, for auto compo. */
- short recalc;
-
- /** Direction for offsetting nodes on insertion. */
- char insert_ofs_dir;
- char _pad4;
-
- /** Temporary data for modal linking operator. */
- ListBase linkdrag;
- /* 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;
/** Grease-pencil data. */
struct bGPdata *gpd;
+
+ SpaceNode_Runtime *runtime;
} SpaceNode;
/* SpaceNode.flag */
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
index 5b6b706c83c..f08aee317a3 100644
--- a/source/blender/makesdna/DNA_tracking_types.h
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -141,7 +141,7 @@ typedef struct MovieTrackingTrack {
/** Count of markers in track. */
int markersnr;
/** Most recently used marker. */
- int last_marker;
+ int _pad;
/** Markers in track. */
MovieTrackingMarker *markers;
@@ -251,8 +251,6 @@ typedef struct MovieTrackingPlaneTrack {
} MovieTrackingPlaneTrack;
typedef struct MovieTrackingSettings {
- int flag;
-
/* ** default tracker settings */
/** Model of the motion for this track. */
short default_motion_model;
@@ -309,8 +307,6 @@ typedef struct MovieTrackingSettings {
/* set object scale */
/** Distance between two bundles used for object scaling. */
float object_distance;
-
- char _pad3[4];
} MovieTrackingSettings;
typedef struct MovieTrackingStabilization {
@@ -526,12 +522,6 @@ typedef enum eTrackFrameMatch {
TRACK_MATCH_PREVIOS_FRAME = 1,
} eTrackFrameMatch;
-/* MovieTrackingSettings->flag */
-enum {
- TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED = (1 << 0),
- TRACKING_SETTINGS_SHOW_EXTRA_EXPANDED = (1 << 1),
-};
-
/* MovieTrackingSettings->motion_flag */
enum {
TRACKING_MOTION_TRIPOD = (1 << 0),
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index f620602f051..0e31ec3494e 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -762,8 +762,12 @@ typedef struct UserDef {
char _pad13[4];
struct SolidLight light_param[4];
float light_ambient[3];
- char _pad3[4];
- short gizmo_flag, gizmo_size;
+ char gizmo_flag;
+ /** Generic gizmo size. */
+ char gizmo_size;
+ /** Navigate gizmo size. */
+ char gizmo_size_navigate_v3d;
+ char _pad3[5];
short edit_studio_light;
short lookdev_sphere_size;
short vbotimeout, vbocollectrate;
@@ -1009,8 +1013,11 @@ typedef enum ePathCompare_Flag {
/** #UserDef.viewzoom */
typedef enum eViewZoom_Style {
- USER_ZOOM_CONT = 0,
+ /** Update zoom continuously with a timer while dragging the cursor. */
+ USER_ZOOM_CONTINUE = 0,
+ /** Map changes in distance from the view center to zoom. */
USER_ZOOM_SCALE = 1,
+ /** Map horizontal/vertical motion to zoom. */
USER_ZOOM_DOLLY = 2,
} eViewZoom_Style;
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index f07af2c14a0..a3aaf3ee937 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -215,7 +215,7 @@ enum {
(WM_OUTLINER_SYNC_SELECT_FROM_OBJECT | WM_OUTLINER_SYNC_SELECT_FROM_EDIT_BONE | \
WM_OUTLINER_SYNC_SELECT_FROM_POSE_BONE | WM_OUTLINER_SYNC_SELECT_FROM_SEQUENCE)
-#define WM_KEYCONFIG_STR_DEFAULT "blender"
+#define WM_KEYCONFIG_STR_DEFAULT "Blender"
/* IME is win32 only! */
#if !defined(WIN32) && !defined(DNA_DEPRECATED)
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt
index eb7779213fd..db34cf83fa9 100644
--- a/source/blender/makesdna/intern/CMakeLists.txt
+++ b/source/blender/makesdna/intern/CMakeLists.txt
@@ -48,12 +48,6 @@ set(SRC
../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c
)
-if(WIN32 AND NOT UNIX)
- list(APPEND SRC
- ../../../../intern/guardedalloc/intern/mmap_win.c
- )
-endif()
-
# SRC_DNA_INC is defined in the parent dir
add_cc_flags_custom_test(makesdna)
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 54d2bc88d16..7624649bf78 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -397,13 +397,11 @@ static int add_type(const char *str, int size)
}
/**
- *
* Because of the weird way of tokenizing, we have to 'cast' function
* pointers to ... (*f)(), whatever the original signature. In fact,
* we add name and type at the same time... There are two special
* cases, unfortunately. These are explicitly checked.
- *
- * */
+ */
static int add_name(const char *str)
{
char buf[255]; /* stupid limit, change it :) */
@@ -479,17 +477,16 @@ static int add_name(const char *str)
}
/*
- * Put )(void) at the end? Maybe )(). Should check this with
- * old sdna. Actually, sometimes )(), sometimes )(void...)
+ * Put `)(void)` at the end? Maybe `)()`. Should check this with
+ * old `sdna`. Actually, sometimes `)()`, sometimes `)(void...)`
* Alas.. such is the nature of brain-damage :(
*
- * Sorted it out: always do )(), except for headdraw and
- * windraw, part of ScrArea. This is important, because some
+ * Sorted it out: always do )(), except for `headdraw` and
+ * `windraw`, part of #ScrArea. This is important, because some
* linkers will treat different fp's differently when called
* !!! This has to do with interference in byte-alignment and
- * the way args are pushed on the stack.
- *
- * */
+ * the way arguments are pushed on the stack.
+ */
buf[i] = 0;
DEBUG_PRINTF(3, "Name before chomping: %s\n", buf);
if ((strncmp(buf, "(*headdraw", 10) == 0) || (strncmp(buf, "(*windraw", 9) == 0)) {
@@ -1077,7 +1074,7 @@ static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char
}
}
- if (size_native % 4) {
+ if (size_native % 4 && !ELEM(size_native, 1, 2)) {
fprintf(stderr,
"Sizeerror 4 in struct: %s (add %d bytes)\n",
types[structtype],
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 35b174f0da8..eaa2675573c 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -91,6 +91,7 @@ extern StructRNA RNA_BoidSettings;
extern StructRNA RNA_BoidState;
extern StructRNA RNA_Bone;
extern StructRNA RNA_BoneGroup;
+extern StructRNA RNA_BoolAttribute;
extern StructRNA RNA_BoolProperty;
extern StructRNA RNA_BooleanModifier;
extern StructRNA RNA_Brush;
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 72cdaecb2c3..94cfd8464ae 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -189,7 +189,6 @@ set(SRC
../../../../intern/guardedalloc/intern/mallocn.c
../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c
../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c
- ../../../../intern/guardedalloc/intern/mmap_win.c
# Needed for defaults.
../../../../release/datafiles/userdef/userdef_default.c
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index e9e00ff6f71..bec3db10905 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -4758,8 +4758,14 @@ static const char *cpp_classes =
"class CollectionIterator {\n"
"public:\n"
" CollectionIterator() : iter(), t(iter.ptr), init(false) { iter.valid = false; }\n"
+ " CollectionIterator(const PointerRNA &ptr) : CollectionIterator() { this->begin(ptr); }\n"
" ~CollectionIterator(void) { if (init) Tend(&iter); };\n"
"\n"
+ " CollectionIterator(const CollectionIterator &other) = delete;\n"
+ " CollectionIterator(CollectionIterator &&other) = delete;\n"
+ " CollectionIterator &operator=(const CollectionIterator &other) = delete;\n"
+ " CollectionIterator &operator=(CollectionIterator &&other) = delete;\n"
+ "\n"
" operator bool(void)\n"
" { return iter.valid != 0; }\n"
" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator++() { Tnext(&iter); t = "
@@ -4777,9 +4783,6 @@ static const char *cpp_classes =
"true; }\n"
"\n"
"private:\n"
- " const CollectionIterator<T, Tbegin, Tnext, Tend>& operator = "
- "(const CollectionIterator<T, Tbegin, Tnext, Tend>& /*copy*/) {}\n"
- ""
" CollectionPropertyIterator iter;\n"
" T t;\n"
" bool init;\n"
@@ -4794,6 +4797,8 @@ static const char *cpp_classes =
"\n"
" void begin(CollectionIterator<T, Tbegin, Tnext, Tend>& iter)\n"
" { iter.begin(ptr); }\n"
+ " CollectionIterator<T, Tbegin, Tnext, Tend> begin()\n"
+ " { return CollectionIterator<T, Tbegin, Tnext, Tend>(ptr); }\n"
" CollectionIterator<T, Tbegin, Tnext, Tend> end()\n"
" { return CollectionIterator<T, Tbegin, Tnext, Tend>(); } /* test */ \n"
""
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index ae23e0b9109..d8c91cb2923 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -3704,7 +3704,7 @@ void RNA_property_pointer_set(PointerRNA *ptr,
}
}
else {
- /* Assigning to an IDProperty desguised as RNA one. */
+ /* Assigning to an IDProperty disguised as RNA one. */
if (ptr_value.type != NULL && !RNA_struct_is_a(ptr_value.type, &RNA_ID)) {
BKE_reportf(reports,
RPT_ERROR,
@@ -3741,7 +3741,7 @@ void RNA_property_pointer_set(PointerRNA *ptr,
pprop->set(ptr, ptr_value, reports);
}
}
- /* IDProperty desguised as RNA property (and not yet defined in ptr). */
+ /* IDProperty disguised as RNA property (and not yet defined in ptr). */
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -6174,7 +6174,7 @@ char *RNA_path_full_property_py_ex(
}
else {
if (use_fallback) {
- /* fuzzy fallback. be explicit in our ignoranc. */
+ /* Fuzzy fallback. Be explicit in our ignorance. */
data_path = RNA_property_identifier(prop);
data_delim = " ... ";
}
diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c
index 1e7f5e841ba..d6305388cf9 100644
--- a/source/blender/makesrna/intern/rna_access_compare_override.c
+++ b/source/blender/makesrna/intern/rna_access_compare_override.c
@@ -42,6 +42,7 @@
#include "BKE_armature.h"
#include "BKE_idprop.h"
+#include "BKE_idtype.h"
#include "BKE_lib_override.h"
#include "BKE_main.h"
@@ -133,7 +134,7 @@ bool RNA_property_overridable_get(PointerRNA *ptr, PropertyRNA *prop)
/* Special handling for insertions of constraints or modifiers... */
/* TODO Note We may want to add a more generic system to RNA
* (like a special property in struct of items)
- * if we get more overrideable collections,
+ * if we get more overridable collections,
* for now we can live with those special-cases handling I think. */
if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
bConstraint *con = ptr->data;
@@ -1178,6 +1179,17 @@ void RNA_struct_override_apply(Main *bmain,
#endif
}
}
+
+ /* Some cases (like point caches) may require additional post-processing. */
+ if (RNA_struct_is_a(ptr_dst->type, &RNA_ID)) {
+ ID *id_dst = ptr_dst->data;
+ ID *id_src = ptr_src->data;
+ const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id_dst);
+ if (id_type->lib_override_apply_post != NULL) {
+ id_type->lib_override_apply_post(id_dst, id_src);
+ }
+ }
+
#ifdef DEBUG_OVERRIDE_TIMEIT
TIMEIT_END_AVERAGED(RNA_struct_override_apply);
#endif
diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c
index 06215e16965..8e95388fe2b 100644
--- a/source/blender/makesrna/intern/rna_animviz.c
+++ b/source/blender/makesrna/intern/rna_animviz.c
@@ -61,7 +61,7 @@ static void rna_AnimViz_path_start_frame_set(PointerRNA *ptr, int value)
{
bAnimVizSettings *data = (bAnimVizSettings *)ptr->data;
- /* XXX: watchit! Path Start > MAXFRAME/2 could be a problem... */
+ /* XXX: Watch it! Path Start > MAXFRAME/2 could be a problem. */
data->path_sf = value;
FRAMENUMBER_MIN_CLAMP(data->path_sf);
diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c
index 7cd6e375a82..21b26b51e0a 100644
--- a/source/blender/makesrna/intern/rna_attribute.c
+++ b/source/blender/makesrna/intern/rna_attribute.c
@@ -169,6 +169,9 @@ static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRN
case CD_PROP_STRING:
struct_size = sizeof(MStringProperty);
break;
+ case CD_PROP_BOOL:
+ struct_size = sizeof(MBoolProperty);
+ break;
default:
struct_size = 0;
length = 0;
@@ -299,6 +302,9 @@ PointerRNA rna_AttributeGroup_iterator_get(CollectionPropertyIterator *iter)
case CD_PROP_STRING:
type = &RNA_StringAttribute;
break;
+ case CD_PROP_BOOL:
+ type = &RNA_BoolAttribute;
+ break;
default:
return PointerRNA_NULL;
}
@@ -555,6 +561,34 @@ static void rna_def_attribute_string(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}
+static void rna_def_attribute_bool(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "BoolAttribute", "Attribute");
+ RNA_def_struct_sdna(srna, "CustomDataLayer");
+ RNA_def_struct_ui_text(srna, "Bool Attribute", "Bool geometry attribute");
+
+ prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "BoolAttributeValue");
+ RNA_def_property_collection_funcs(prop,
+ "rna_Attribute_data_begin",
+ "rna_iterator_array_next",
+ "rna_iterator_array_end",
+ "rna_iterator_array_get",
+ "rna_Attribute_data_length",
+ NULL,
+ NULL,
+ NULL);
+
+ srna = RNA_def_struct(brna, "BoolAttributeValue", NULL);
+ RNA_def_struct_sdna(srna, "MBoolProperty");
+ RNA_def_struct_ui_text(srna, "Bool Attribute Value", "Bool value in geometry attribute");
+ prop = RNA_def_property(srna, "value", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "b", 0x01);
+}
+
static void rna_def_attribute(BlenderRNA *brna)
{
PropertyRNA *prop;
@@ -592,6 +626,7 @@ static void rna_def_attribute(BlenderRNA *brna)
rna_def_attribute_byte_color(brna);
rna_def_attribute_int(brna);
rna_def_attribute_string(brna);
+ rna_def_attribute_bool(brna);
}
/* Mesh/PointCloud/Hair.attributes */
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 2af6c04147c..3dcc9471906 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1304,7 +1304,7 @@ 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);
- /* Randomnes factor for pressure */
+ /* Randomness factor for pressure */
prop = RNA_def_property(srna, "random_pressure", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "draw_random_press");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -1313,7 +1313,7 @@ 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);
- /* Randomnes factor for strength */
+ /* Randomness factor for strength */
prop = RNA_def_property(srna, "random_strength", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "draw_random_strength");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -1446,7 +1446,7 @@ 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 threshold for transparence */
+ /* Fill threshold for transparency. */
prop = RNA_def_property(srna, "fill_threshold", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "fill_threshold");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -1464,13 +1464,13 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
/* fill factor size */
- prop = RNA_def_property(srna, "fill_factor", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "fill_factor");
- RNA_def_property_range(prop, 1, 8);
+ prop = RNA_def_property(srna, "fill_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "fill_factor");
+ RNA_def_property_range(prop, GPENCIL_MIN_FILL_FAC, GPENCIL_MAX_FILL_FAC);
RNA_def_property_ui_text(
prop,
- "Resolution",
- "Multiplier for fill resolution, higher resolution is more accurate but slower");
+ "Precision",
+ "Factor for fill boundary accuracy, higher values are more accurate but slower");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
@@ -1608,6 +1608,15 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Value", "Random factor to modify original value");
RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
+ /* Factor to extend stroke extremes in Fill tool. */
+ prop = RNA_def_property(srna, "extend_stroke_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "fill_extend_fac");
+ 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");
+ RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
+
/* Flags */
prop = RNA_def_property(srna, "use_pressure", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_PRESSURE);
@@ -1827,6 +1836,12 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Lines", "Show help lines for filling to see boundaries");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ 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_clear_flag(prop, PROP_ANIMATABLE);
+
prop = RNA_def_property(srna, "show_fill", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_BRUSH_FILL_HIDE);
RNA_def_property_boolean_default(prop, true);
@@ -1834,6 +1849,12 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
prop, "Show Fill", "Show transparent lines to use as boundary for filling");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ prop = RNA_def_property(srna, "use_fill_limit", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_FILL_FIT_DISABLE);
+ RNA_def_property_boolean_default(prop, true);
+ RNA_def_property_ui_text(prop, "Limit to Viewport", "Fill only visible areas in viewport");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
prop = RNA_def_property(srna, "use_default_eraser", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_DEFAULT_ERASER);
RNA_def_property_boolean_default(prop, true);
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 4f5828311d8..843cb326be2 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -3032,7 +3032,7 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
prop, "Use Original Scale", "Apply volume preservation over the original scaling");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
- /* volume presevation for "volumetric" scale mode */
+ /* Volume preservation for "volumetric" scale mode. */
prop = RNA_def_property(srna, "bulge", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 100.0f);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index cec6a50d170..df3bd0cca29 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -1298,7 +1298,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_,
dcont = rna_find_container_def(cont);
- /* XXX - toto, detect supertype collisions */
+ /* TODO: detect super-type collisions. */
if (rna_findlink(&dcont->properties, identifier)) {
CLOG_ERROR(&LOG, "duplicate identifier \"%s.%s\"", CONTAINER_RNA_ID(cont), identifier);
DefRNA.error = true;
@@ -4111,6 +4111,16 @@ PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_,
ASSERT_SOFT_HARD_LIMITS;
+#ifdef DEBUG
+ /* Properties with PROP_PERCENTAGE should use a range like 0 to 100, unlike PROP_FACTOR. */
+ if (hardmax < 2.0f) {
+ CLOG_WARN(&LOG,
+ "Percentage property with incorrect range: %s.%s",
+ CONTAINER_RNA_ID(cont),
+ identifier);
+ }
+#endif
+
prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE);
RNA_def_property_float_default(prop, default_value);
if (hardmin != hardmax) {
diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index cbb642577e1..aab81b2bd1f 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -684,7 +684,7 @@ static void rna_def_depsgraph(BlenderRNA *brna)
"This invalidates all references to evaluated data-blocks from this dependency graph.");
RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
- /* Queries for original datablockls (the ones depsgraph is built for). */
+ /* Queries for original data-blocks (the ones depsgraph is built for). */
prop = RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Scene");
@@ -699,7 +699,7 @@ static void rna_def_depsgraph(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "View Layer", "Original view layer dependency graph is built for");
- /* Queries for evaluated datablockls (the ones depsgraph is evaluating). */
+ /* Queries for evaluated data-blocks (the ones depsgraph is evaluating). */
func = RNA_def_function(srna, "id_eval_get", "rna_Depsgraph_id_eval_get");
parm = RNA_def_pointer(
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index 7c4762aa3a3..83df997b3d4 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -625,7 +625,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_OUT1);
RNA_def_property_ui_text(prop, "Use Output", "Save this output layer");
- /* output for secondary sufrace data */
+ /* Output for secondary surface data. */
prop = RNA_def_property(srna, "output_name_b", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "output_name2");
RNA_def_property_ui_text(prop, "Output Name", "Name used to save output from this surface");
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index 3ea98d610f4..a34c3c7b536 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -1964,7 +1964,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(
prop,
"Tension",
- "Surface tension of liquid (higher value results in greater hydrophobic behaviour)");
+ "Surface tension of liquid (higher value results in greater hydrophobic behavior)");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
prop = RNA_def_property(srna, "viscosity_base", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 81e20003d8f..5437c93ef61 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -168,6 +168,7 @@ static const EnumPropertyItem rna_enum_gpencil_caps_modes_items[] = {
# include "BKE_action.h"
# include "BKE_animsys.h"
+# include "BKE_deform.h"
# include "BKE_gpencil.h"
# include "BKE_gpencil_curve.h"
# include "BKE_gpencil_geom.h"
@@ -182,6 +183,16 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
}
+static void rna_GpencilLayerMatrix_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bGPDlayer *gpl = (bGPDlayer *)ptr->data;
+
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
+ rna_GPencil_update(bmain, scene, ptr);
+}
+
static void rna_GPencil_curve_edit_mode_toggle(Main *bmain, Scene *scene, PointerRNA *ptr)
{
ToolSettings *ts = scene->toolsettings;
@@ -806,6 +817,74 @@ static void rna_GPencil_stroke_point_pop(ID *id,
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
}
+static void rna_GPencil_stroke_point_update(ID *id, bGPDstroke *stroke)
+{
+ bGPdata *gpd = (bGPdata *)id;
+
+ /* Calc geometry data. */
+ if (stroke) {
+ BKE_gpencil_stroke_geometry_update(gpd, stroke);
+
+ DEG_id_tag_update(&gpd->id,
+ ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+
+ WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
+ }
+}
+
+static float rna_GPencilStrokePoints_weight_get(bGPDstroke *stroke,
+ ReportList *reports,
+ int vertex_group_index,
+ int point_index)
+{
+ MDeformVert *dvert = stroke->dvert;
+ if (dvert == NULL) {
+ BKE_report(reports, RPT_ERROR, "Groups: No groups for this stroke");
+ return -1.0f;
+ }
+
+ if (dvert->totweight <= vertex_group_index || vertex_group_index < 0) {
+ BKE_report(reports, RPT_ERROR, "Groups: index out of range");
+ return -1.0f;
+ }
+
+ if (stroke->totpoints <= point_index || point_index < 0) {
+ BKE_report(reports, RPT_ERROR, "GPencilStrokePoints: index out of range");
+ return -1.0f;
+ }
+
+ MDeformVert *pt_dvert = stroke->dvert + point_index;
+ MDeformWeight *dw = BKE_defvert_find_index(pt_dvert, vertex_group_index);
+ if (dw) {
+ return dw->weight;
+ }
+
+ return -1.0f;
+}
+
+static void rna_GPencilStrokePoints_weight_set(
+ bGPDstroke *stroke, ReportList *reports, int vertex_group_index, int point_index, float weight)
+{
+ BKE_gpencil_dvert_ensure(stroke);
+
+ MDeformVert *dvert = stroke->dvert;
+ if (dvert == NULL) {
+ BKE_report(reports, RPT_ERROR, "Groups: No groups for this stroke");
+ return;
+ }
+
+ if (stroke->totpoints <= point_index || point_index < 0) {
+ BKE_report(reports, RPT_ERROR, "GPencilStrokePoints: index out of range");
+ return;
+ }
+
+ MDeformVert *pt_dvert = stroke->dvert + point_index;
+ MDeformWeight *dw = BKE_defvert_ensure_index(pt_dvert, vertex_group_index);
+ if (dw) {
+ dw->weight = weight;
+ }
+}
+
static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame)
{
bGPDstroke *stroke = BKE_gpencil_stroke_new(0, 0, 1.0f);
@@ -940,7 +1019,7 @@ static void rna_GPencil_frame_remove(bGPDlayer *layer, ReportList *reports, Poin
static bGPDframe *rna_GPencil_frame_copy(bGPDlayer *layer, bGPDframe *src)
{
- bGPDframe *frame = BKE_gpencil_frame_duplicate(src);
+ bGPDframe *frame = BKE_gpencil_frame_duplicate(src, true);
while (BKE_gpencil_layer_frame_find(layer, frame->framenum)) {
frame->framenum++;
@@ -1044,21 +1123,6 @@ static void rna_GPencil_clear(bGPdata *gpd)
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
-static void rna_GpencilVertex_groups_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
-{
- bGPDstroke *gps = ptr->data;
-
- if (gps->dvert) {
- MDeformVert *dvert = gps->dvert;
-
- rna_iterator_array_begin(
- iter, (void *)dvert->dw, sizeof(MDeformWeight), dvert->totweight, 0, NULL);
- }
- else {
- rna_iterator_array_begin(iter, NULL, 0, 0, 0, NULL);
- }
-}
-
static char *rna_GreasePencilGrid_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("grid");
@@ -1264,6 +1328,58 @@ static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cpr
RNA_def_function_ui_description(func, "Remove a grease pencil stroke point");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
RNA_def_int(func, "index", -1, INT_MIN, INT_MAX, "Index", "point index", INT_MIN, INT_MAX);
+
+ func = RNA_def_function(srna, "update", "rna_GPencil_stroke_point_update");
+ RNA_def_function_ui_description(func, "Recalculate internal triangulation data");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+
+ func = RNA_def_function(srna, "weight_get", "rna_GPencilStrokePoints_weight_get");
+ RNA_def_function_ui_description(func, "Get vertex group point weight");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_int(func,
+ "vertex_group_index",
+ 0,
+ 0,
+ INT_MAX,
+ "Vertex Group Index",
+ "Index of Vertex Group in the array of groups",
+ 0,
+ INT_MAX);
+ RNA_def_int(func,
+ "point_index",
+ 0,
+ 0,
+ INT_MAX,
+ "Point Index",
+ "Index of the Point in the array",
+ 0,
+ INT_MAX);
+ parm = RNA_def_float(
+ func, "weight", 0, -FLT_MAX, FLT_MAX, "Weight", "Point Weight", -FLT_MAX, FLT_MAX);
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "weight_set", "rna_GPencilStrokePoints_weight_set");
+ RNA_def_function_ui_description(func, "Set vertex group point weight");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_int(func,
+ "vertex_group_index",
+ 0,
+ 0,
+ INT_MAX,
+ "Vertex Group Index",
+ "Index of Vertex Group in the array of groups",
+ 0,
+ INT_MAX);
+ RNA_def_int(func,
+ "point_index",
+ 0,
+ 0,
+ INT_MAX,
+ "Point Index",
+ "Index of the Point in the array",
+ 0,
+ INT_MAX);
+ RNA_def_float(func, "weight", 0, -FLT_MAX, FLT_MAX, "Weight", "Point Weight", -FLT_MAX, FLT_MAX);
}
/* This information is read only and it can be used by add-ons */
@@ -1491,21 +1607,6 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points");
rna_def_gpencil_stroke_points_api(brna, prop);
- /* vertex groups */
- prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_funcs(prop,
- "rna_GpencilVertex_groups_begin",
- "rna_iterator_array_next",
- "rna_iterator_array_end",
- "rna_iterator_array_get",
- NULL,
- NULL,
- NULL,
- NULL);
- RNA_def_property_struct_type(prop, "GpencilVertexGroupElement");
- RNA_def_property_ui_text(
- prop, "Groups", "Weights for the vertex groups this vertex is member of");
-
/* Triangles */
prop = RNA_def_property(srna, "triangles", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "triangles", "tot_triangles");
@@ -2012,6 +2113,45 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Blend Mode", "Blend mode");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+ /* Layer transforms. */
+ prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "location");
+ RNA_def_property_ui_text(prop, "Location", "Values for change location");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
+ RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
+
+ prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
+ RNA_def_property_float_sdna(prop, NULL, "rotation");
+ RNA_def_property_ui_text(prop, "Rotation", "Values for changes in rotation");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
+ RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
+
+ prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "scale");
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Scale", "Values for changes in scale");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
+ RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
+
+ /* Layer matrix. */
+ prop = RNA_def_property(srna, "matrix_layer", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "layer_mat");
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
+ RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_ui_text(prop, "Matrix Layer", "Local Layer transformation matrix");
+
+ /* Layer inverse matrix. */
+ prop = RNA_def_property(srna, "matrix_inverse_layer", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "layer_invmat");
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
+ RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_ui_text(
+ prop, "Matrix Layer Inverse", "Local Layer transformation inverse matrix");
+
/* Flags */
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 89eb989a442..71d5a53adb2 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -489,7 +489,7 @@ static void rna_def_modifier_gpencilnoise(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_ui_text(prop, "Seed", "Random seed");
+ RNA_def_property_ui_text(prop, "Noise Seed", "Random seed");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "noise_scale", PROP_FLOAT, PROP_FACTOR);
@@ -498,6 +498,13 @@ static void rna_def_modifier_gpencilnoise(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Noise Scale", "Scale the noise frequency");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+ prop = RNA_def_property(srna, "noise_offset", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "noise_offset");
+ RNA_def_property_range(prop, 0.0, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0, 100.0, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Noise Offset", "Offset the noise along the strokes");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
prop = RNA_def_property(srna, "use_custom_curve", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_CUSTOM_CURVE);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c
index 25472ce9520..319aeb69a2b 100644
--- a/source/blender/makesrna/intern/rna_lattice.c
+++ b/source/blender/makesrna/intern/rna_lattice.c
@@ -132,12 +132,12 @@ static void rna_Lattice_update_size(Main *bmain, Scene *scene, PointerRNA *ptr)
Object *ob;
int newu, newv, neww;
- /* we don't modify the actual pnts, but go through opnts instead */
+ /* We don't modify the actual `pnts`, but go through `opnts` instead. */
newu = (lt->opntsu > 0) ? lt->opntsu : lt->pntsu;
newv = (lt->opntsv > 0) ? lt->opntsv : lt->pntsv;
neww = (lt->opntsw > 0) ? lt->opntsw : lt->pntsw;
- /* BKE_lattice_resize needs an object, any object will have the same result */
+ /* #BKE_lattice_resize needs an object, any object will have the same result */
for (ob = bmain->objects.first; ob; ob = ob->id.next) {
if (ob->data == lt) {
BKE_lattice_resize(lt, newu, newv, neww, ob);
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index d162917ea0c..f92a2932f06 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -288,7 +288,7 @@ void RNA_api_mesh(StructRNA *srna)
"Define custom split normals of this mesh "
"(use zero-vectors to keep auto ones)");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
- /* TODO, see how array size of 0 works, this shouldnt be used */
+ /* TODO, see how array size of 0 works, this shouldn't be used */
parm = RNA_def_float_array(func, "normals", 1, NULL, -1.0f, 1.0f, "", "Normals", 0.0f, 0.0f);
RNA_def_property_multi_array(parm, 2, normals_array_dim);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
@@ -301,7 +301,7 @@ void RNA_api_mesh(StructRNA *srna)
"Define custom split normals of this mesh, from vertices' normals "
"(use zero-vectors to keep auto ones)");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
- /* TODO, see how array size of 0 works, this shouldnt be used */
+ /* TODO, see how array size of 0 works, this shouldn't be used */
parm = RNA_def_float_array(func, "normals", 1, NULL, -1.0f, 1.0f, "", "Normals", 0.0f, 0.0f);
RNA_def_property_multi_array(parm, 2, normals_array_dim);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index e02e47745b0..7209d17735a 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -681,7 +681,7 @@ static void rna_Modifier_is_active_set(PointerRNA *ptr, bool value)
ModifierData *md = ptr->data;
if (value) {
- /* Disable the active flag of all other modif-iers. */
+ /* Disable the active flag of all other modifiers. */
for (ModifierData *prev_md = md->prev; prev_md != NULL; prev_md = prev_md->prev) {
prev_md->flag &= ~eModifierFlag_Active;
}
@@ -1632,33 +1632,35 @@ static IDProperty *rna_NodesModifier_properties(PointerRNA *ptr, bool create)
static void rna_def_property_subdivision_common(StructRNA *srna)
{
static const EnumPropertyItem prop_uv_smooth_items[] = {
- {SUBSURF_UV_SMOOTH_NONE, "NONE", 0, "None", "UVs are not smoothed, boundaries are kept sharp"},
- {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS,
- "PRESERVE_CORNERS",
- 0,
- "Keep Corners",
- "UVs are smoothed, corners on discontinuous boundary are kept sharp"},
-# if 0
- {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS,
- "PRESERVE_CORNERS_AND_JUNCTIONS",
- 0,
- "Smooth, keep corners+junctions",
- "UVs are smoothed, corners on discontinuous boundary and "
- "junctions of 3 or more regions are kept sharp"},
- {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE,
- "PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE",
- 0,
- "Smooth, keep corners+junctions+concave",
- "UVs are smoothed, corners on discontinuous boundary, "
- "junctions of 3 or more regions and darts and concave corners are kept sharp"},
- {SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES,
- "PRESERVE_BOUNDARIES",
- 0,
- "Smooth, keep corners",
- "UVs are smoothed, boundaries are kept sharp"},
-# endif
- {SUBSURF_UV_SMOOTH_ALL, "PRESERVE_BOUNDARIES", 0, "All", "UVs and boundaries are smoothed"},
- {0, NULL, 0, NULL, NULL},
+ {SUBSURF_UV_SMOOTH_NONE,
+ "NONE",
+ 0,
+ "None",
+ "UVs are not smoothed, boundaries are kept sharp"},
+ {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS,
+ "PRESERVE_CORNERS",
+ 0,
+ "Keep Corners",
+ "UVs are smoothed, corners on discontinuous boundary are kept sharp"},
+ {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS,
+ "PRESERVE_CORNERS_AND_JUNCTIONS",
+ 0,
+ "Keep Corners, Junctions",
+ "UVs are smoothed, corners on discontinuous boundary and "
+ "junctions of 3 or more regions are kept sharp"},
+ {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE,
+ "PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE",
+ 0,
+ "Keep Corners, Junctions, Concave",
+ "UVs are smoothed, corners on discontinuous boundary, "
+ "junctions of 3 or more regions and darts and concave corners are kept sharp"},
+ {SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES,
+ "PRESERVE_BOUNDARIES",
+ 0,
+ "Keep boundaries",
+ "UVs are smoothed, boundaries are kept sharp"},
+ {SUBSURF_UV_SMOOTH_ALL, "SMOOTH_ALL", 0, "All", "UVs and boundaries are smoothed"},
+ {0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem prop_boundary_smooth_items[] = {
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index f9b5041b1cf..610edb0e37c 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -29,6 +29,7 @@
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
@@ -1964,22 +1965,6 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeFill_domain_itemf(
return itemf_function_check(rna_enum_attribute_domain_items, attribute_fill_domain_supported);
}
-static bool attribute_math_operation_supported(const EnumPropertyItem *item)
-{
- return ELEM(item->value,
- NODE_MATH_ADD,
- NODE_MATH_SUBTRACT,
- NODE_MATH_MULTIPLY,
- NODE_MATH_DIVIDE) &&
- (item->identifier[0] != '\0');
-}
-static const EnumPropertyItem *rna_GeometryNodeAttributeMath_operation_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
- *r_free = true;
- return itemf_function_check(rna_enum_node_math_items, attribute_math_operation_supported);
-}
-
/**
* This bit of ugly code makes sure the float / attribute option shows up instead of
* vector / attribute if the node uses an operation that uses a float for input B.
@@ -4741,9 +4726,10 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_float_default(prop, 0.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
- prop = RNA_def_property(srna, "altitude", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "altitude", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_ui_text(prop, "Altitude", "Height from sea level");
- RNA_def_property_range(prop, 0.0f, 60.0f);
+ RNA_def_property_range(prop, 0.0f, 60000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 60000.0f, 10, 1);
RNA_def_property_float_default(prop, 0.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -5395,7 +5381,7 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
func = RNA_def_function(srna, "calc_point_density", "rna_ShaderNodePointDensity_density_calc");
RNA_def_function_ui_description(func, "Calculate point density");
RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
- /* TODO, See how array size of 0 works, this shouldnt be used. */
+ /* TODO, See how array size of 0 works, this shouldn't be used. */
parm = RNA_def_float_array(func, "rgba_values", 1, NULL, 0, 0, "", "RGBA Values", 0, 0);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, 0);
RNA_def_function_output(func, parm);
@@ -8563,10 +8549,9 @@ static void def_geo_attribute_math(StructRNA *srna)
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "operation");
RNA_def_property_enum_items(prop, rna_enum_node_math_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeMath_operation_itemf");
RNA_def_property_enum_default(prop, NODE_MATH_ADD);
RNA_def_property_ui_text(prop, "Operation", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
prop = RNA_def_property(srna, "input_type_a", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_a");
@@ -8579,6 +8564,12 @@ static void def_geo_attribute_math(StructRNA *srna)
RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
RNA_def_property_ui_text(prop, "Input Type B", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+
+ prop = RNA_def_property(srna, "input_type_c", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_c");
+ RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
+ RNA_def_property_ui_text(prop, "Input Type C", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_geo_attribute_vector_math(StructRNA *srna)
@@ -8632,16 +8623,17 @@ static void def_geo_point_instance(StructRNA *srna)
};
PropertyRNA *prop;
+ RNA_def_struct_sdna_from(srna, "NodeGeometryPointInstance", "storage");
prop = RNA_def_property(srna, "instance_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_sdna(prop, NULL, "instance_type");
RNA_def_property_enum_items(prop, instance_type_items);
RNA_def_property_enum_default(prop, GEO_NODE_POINT_INSTANCE_TYPE_OBJECT);
RNA_def_property_ui_text(prop, "Instance Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
prop = RNA_def_property(srna, "use_whole_collection", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION);
RNA_def_property_ui_text(prop, "Whole Collection", "Instance entire collection on each point");
RNA_def_property_update(prop, 0, "rna_Node_socket_update");
}
@@ -8682,7 +8674,7 @@ static void def_geo_attribute_attribute_compare(StructRNA *srna)
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_node_float_compare_items);
- RNA_def_property_enum_default(prop, NODE_MATH_ADD);
+ RNA_def_property_enum_default(prop, NODE_FLOAT_COMPARE_GREATER_THAN);
RNA_def_property_ui_text(prop, "Operation", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
@@ -8802,6 +8794,30 @@ static void def_geo_align_rotation_to_vector(StructRNA *srna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem pivot_axis_items[] = {
+ {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_AUTO,
+ "AUTO",
+ ICON_NONE,
+ "Auto",
+ "Automatically detect the best rotation axis to rotate towards the vector"},
+ {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_X,
+ "X",
+ ICON_NONE,
+ "X",
+ "Rotate around the local X axis"},
+ {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_Y,
+ "Y",
+ ICON_NONE,
+ "Y",
+ "Rotate around the local Y axis"},
+ {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_Z,
+ "Z",
+ ICON_NONE,
+ "Z",
+ "Rotate around the local Z axis"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeGeometryAlignRotationToVector", "storage");
@@ -8811,6 +8827,11 @@ static void def_geo_align_rotation_to_vector(StructRNA *srna)
RNA_def_property_ui_text(prop, "Axis", "Axis to align to the vector");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ prop = RNA_def_property(srna, "pivot_axis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, pivot_axis_items);
+ RNA_def_property_ui_text(prop, "Pivot Axis", "Axis to rotate around");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
prop = RNA_def_property(srna, "input_type_factor", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
RNA_def_property_ui_text(prop, "Input Type Factor", "");
@@ -8846,6 +8867,19 @@ static void def_geo_point_translate(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
+static void def_geo_attribute_sample_texture(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "Texture");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_ui_text(prop, "Texture", "Texture to sample values from");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update_relations");
+}
+
static void def_geo_object_info(StructRNA *srna)
{
PropertyRNA *prop;
@@ -8876,6 +8910,161 @@ static void def_geo_object_info(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_geo_points_to_volume(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem resolution_mode_items[] = {
+ {GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT,
+ "VOXEL_AMOUNT",
+ 0,
+ "Amount",
+ "Specify the approximate number of voxels along the diagonal"},
+ {GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE,
+ "VOXEL_SIZE",
+ 0,
+ "Size",
+ "Specify the voxel side length"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ RNA_def_struct_sdna_from(srna, "NodeGeometryPointsToVolume", "storage");
+
+ prop = RNA_def_property(srna, "resolution_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, resolution_mode_items);
+ RNA_def_property_ui_text(prop, "Resolution Mode", "How the voxel size is specified");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+
+ prop = RNA_def_property(srna, "input_type_radius", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
+ RNA_def_property_ui_text(prop, "Radius Input Type", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
+static void def_geo_collection_info(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static const EnumPropertyItem rna_node_geometry_collection_info_transform_space_items[] = {
+ {GEO_NODE_TRANSFORM_SPACE_ORIGINAL,
+ "ORIGINAL",
+ 0,
+ "Original",
+ "Output the geometry relative to the collection offset"},
+ {GEO_NODE_TRANSFORM_SPACE_RELATIVE,
+ "RELATIVE",
+ 0,
+ "Relative",
+ "Bring the input collection geometry into the modified object, maintaining the relative "
+ "position between the objects in the scene."},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ RNA_def_struct_sdna_from(srna, "NodeGeometryCollectionInfo", "storage");
+
+ prop = RNA_def_property(srna, "transform_space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_node_geometry_collection_info_transform_space_items);
+ RNA_def_property_ui_text(prop, "Transform Space", "The transformation of the geometry output");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
+static void def_geo_attribute_proximity(StructRNA *srna)
+{
+ static const EnumPropertyItem target_geometry_element[] = {
+ {GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_POINTS,
+ "POINTS",
+ ICON_NONE,
+ "Points",
+ "Calculate proximity to the target's points (usually faster than the other two modes)"},
+ {GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_EDGES,
+ "EDGES",
+ ICON_NONE,
+ "Edges",
+ "Calculate proximity to the target's edges"},
+ {GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_FACES,
+ "FACES",
+ ICON_NONE,
+ "Faces",
+ "Calculate proximity to the target's faces"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ PropertyRNA *prop;
+
+ RNA_def_struct_sdna_from(srna, "NodeGeometryAttributeProximity", "storage");
+
+ prop = RNA_def_property(srna, "target_geometry_element", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, target_geometry_element);
+ RNA_def_property_enum_default(prop, GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_FACES);
+ RNA_def_property_ui_text(
+ prop, "Target Geometry", "Element of the target geometry to calculate the distance from");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
+static void def_geo_volume_to_mesh(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem resolution_mode_items[] = {
+ {VOLUME_TO_MESH_RESOLUTION_MODE_GRID,
+ "GRID",
+ 0,
+ "Grid",
+ "Use resolution of the volume grid"},
+ {VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT,
+ "VOXEL_AMOUNT",
+ 0,
+ "Voxel Amount",
+ "Desired number of voxels along one axis"},
+ {VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE,
+ "VOXEL_SIZE",
+ 0,
+ "Voxel Size",
+ "Desired voxel side length"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ RNA_def_struct_sdna_from(srna, "NodeGeometryVolumeToMesh", "storage");
+
+ prop = RNA_def_property(srna, "resolution_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, resolution_mode_items);
+ RNA_def_property_ui_text(prop, "Resolution Mode", "How the voxel size is specified");
+}
+
+static void def_geo_attribute_combine_xyz(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ RNA_def_struct_sdna_from(srna, "NodeAttributeCombineXYZ", "storage");
+
+ prop = RNA_def_property(srna, "input_type_x", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
+ RNA_def_property_ui_text(prop, "Input Type X", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+
+ prop = RNA_def_property(srna, "input_type_y", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
+ RNA_def_property_ui_text(prop, "Input Type Y", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+
+ prop = RNA_def_property(srna, "input_type_z", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
+ RNA_def_property_ui_text(prop, "Input Type Z", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
+static void def_geo_attribute_separate_xyz(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ RNA_def_struct_sdna_from(srna, "NodeAttributeSeparateXYZ", "storage");
+
+ prop = RNA_def_property(srna, "input_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
+ RNA_def_property_ui_text(prop, "Input Type", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
/* -------------------------------------------------------------------------- */
static void rna_def_shader_node(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index faa20e642cf..1eb5ed3977a 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -85,16 +85,16 @@ const EnumPropertyItem rna_enum_object_mode_items[] = {
ICON_GREASEPENCIL,
"Draw",
"Paint Grease Pencil Strokes"},
- {OB_MODE_VERTEX_GPENCIL,
- "VERTEX_GPENCIL",
- ICON_VPAINT_HLT,
- "Vertex Paint",
- "Grease Pencil Vertex Paint Strokes"},
{OB_MODE_WEIGHT_GPENCIL,
"WEIGHT_GPENCIL",
ICON_WPAINT_HLT,
"Weight Paint",
"Grease Pencil Weight Paint Strokes"},
+ {OB_MODE_VERTEX_GPENCIL,
+ "VERTEX_GPENCIL",
+ ICON_VPAINT_HLT,
+ "Vertex Paint",
+ "Grease Pencil Vertex Paint Strokes"},
{0, NULL, 0, NULL, NULL},
};
@@ -1304,11 +1304,13 @@ static void rna_MaterialSlot_link_set(PointerRNA *ptr, int value)
if (value) {
ob->matbits[index] = 1;
- /* ob->colbits |= (1 << index); */ /* DEPRECATED */
+ /* DEPRECATED */
+ // ob->colbits |= (1 << index);
}
else {
ob->matbits[index] = 0;
- /* ob->colbits &= ~(1 << index); */ /* DEPRECATED */
+ /* DEPRECATED */
+ // ob->colbits &= ~(1 << index);
}
}
@@ -2120,7 +2122,7 @@ static void rna_def_vertex_group(BlenderRNA *brna)
func = RNA_def_function(srna, "add", "rna_VertexGroup_vertex_add");
RNA_def_function_ui_description(func, "Add vertices to the group");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
- /* TODO, see how array size of 0 works, this shouldnt be used */
+ /* TODO, see how array size of 0 works, this shouldn't be used */
parm = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "Index List", 0, 0);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
parm = RNA_def_float(func, "weight", 0, 0.0f, 1.0f, "", "Vertex weight", 0.0f, 1.0f);
@@ -2131,7 +2133,7 @@ static void rna_def_vertex_group(BlenderRNA *brna)
func = RNA_def_function(srna, "remove", "rna_VertexGroup_vertex_remove");
RNA_def_function_ui_description(func, "Remove a vertex from the group");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
- /* TODO, see how array size of 0 works, this shouldnt be used */
+ /* TODO, see how array size of 0 works, this shouldn't be used */
parm = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "Index List", 0, 0);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
@@ -2178,14 +2180,14 @@ static void rna_def_face_map(BlenderRNA *brna)
func = RNA_def_function(srna, "add", "rna_FaceMap_face_add");
RNA_def_function_ui_description(func, "Add vertices to the group");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
- /* TODO, see how array size of 0 works, this shouldnt be used */
+ /* TODO, see how array size of 0 works, this shouldn't be used */
parm = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "Index List", 0, 0);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
func = RNA_def_function(srna, "remove", "rna_FaceMap_face_remove");
RNA_def_function_ui_description(func, "Remove a vertex from the group");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
- /* TODO, see how array size of 0 works, this shouldnt be used */
+ /* TODO, see how array size of 0 works, this shouldn't be used */
parm = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "Index List", 0, 0);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
}
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 3126f3e11f4..0c2860c05e7 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -848,6 +848,14 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Use Eevee Viewport", "Uses Eevee for viewport shading in LookDev shading mode");
+ prop = RNA_def_property(srna, "bl_use_custom_freestyle", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_CUSTOM_FREESTYLE);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_ui_text(
+ prop,
+ "Use Custom Freestyle",
+ "Handles freestyle rendering on its own, instead of delegating it to EEVEE");
+
prop = RNA_def_property(srna, "bl_use_gpu_context", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_GPU_CONTEXT);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index c929e3ab1aa..b0a942cd39e 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -1279,12 +1279,22 @@ static int rna_property_override_diff_propptr(Main *bmain,
0);
if (is_id) {
- /* For now, once we deal with nodetrees we'll want to get rid of that one. */
- // BLI_assert(no_ownership);
+ /* Owned IDs (the ones we want to actually compare in depth, instead of just comparing pointer
+ * values) should be always properly tagged as 'virtual' overrides. */
+ ID *id = propptr_a->owner_id;
+ if (id != NULL && !ID_IS_OVERRIDE_LIBRARY(id)) {
+ id = propptr_b->owner_id;
+ if (id != NULL && !ID_IS_OVERRIDE_LIBRARY(id)) {
+ id = NULL;
+ }
+ }
+
+ BLI_assert(no_ownership || id == NULL || ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id));
+ UNUSED_VARS_NDEBUG(id);
}
if (override) {
- if (no_ownership /* || is_id */ || is_null || is_type_diff || !is_valid_for_diffing) {
+ if (no_ownership || is_null || is_type_diff || !is_valid_for_diffing) {
/* In case this pointer prop does not own its data (or one is NULL), do not compare structs!
* This is a quite safe path to infinite loop, among other nasty issues.
* Instead, just compare pointers themselves. */
@@ -1304,9 +1314,9 @@ static int rna_property_override_diff_propptr(Main *bmain,
BLI_assert(op->rna_prop_type == property_type);
}
+ IDOverrideLibraryPropertyOperation *opop = NULL;
if (created || rna_itemname_a != NULL || rna_itemname_b != NULL ||
rna_itemindex_a != -1 || rna_itemindex_b != -1) {
- IDOverrideLibraryPropertyOperation *opop;
opop = BKE_lib_override_library_property_operation_get(op,
IDOVERRIDE_LIBRARY_OP_REPLACE,
rna_itemname_b,
@@ -1327,6 +1337,38 @@ static int rna_property_override_diff_propptr(Main *bmain,
else {
BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, false);
}
+
+ if (is_id && no_ownership) {
+ if (opop == NULL) {
+ opop = BKE_lib_override_library_property_operation_find(op,
+ rna_itemname_b,
+ rna_itemname_a,
+ rna_itemindex_b,
+ rna_itemindex_a,
+ true,
+ NULL);
+ BLI_assert(opop != NULL);
+ }
+
+ BLI_assert(propptr_a->data == propptr_a->owner_id);
+ BLI_assert(propptr_b->data == propptr_b->owner_id);
+ ID *id_a = propptr_a->data;
+ ID *id_b = propptr_b->data;
+ if (ELEM(NULL, id_a, id_b)) {
+ /* In case one of the pointer is NULL and not the other, we consider that the
+ * override is not matching its reference anymore. */
+ opop->flag &= ~IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE;
+ }
+ else if (id_a->override_library != NULL && id_a->override_library->reference == id_b) {
+ opop->flag |= IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE;
+ }
+ else if (id_b->override_library != NULL && id_b->override_library->reference == id_a) {
+ opop->flag |= IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE;
+ }
+ else {
+ opop->flag &= ~IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE;
+ }
+ }
}
}
@@ -1429,8 +1471,8 @@ static int rna_property_override_diff_propptr(Main *bmain,
}
}
else {
- /* We could also use is_diff_pointer, but then we potentially lose the gt/lt info -
- * and don't think performances are critical here for now anyway... */
+ /* We could also use is_diff_pointer, but then we potentially lose the greater-than/less-than
+ * info - and don't think performances are critical here for now anyway. */
return !RNA_struct_equals(bmain, propptr_a, propptr_b, mode);
}
}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index af31f16f4e0..58a89b7ffdc 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1495,7 +1495,7 @@ static const EnumPropertyItem *rna_ImageFormatSettings_exr_codec_itemf(bContext
int i = 1, totitem = 0;
if (imf->depth == 16) {
- return rna_enum_exr_codec_items; /* All compression types are defined for halfs */
+ return rna_enum_exr_codec_items; /* All compression types are defined for half-float. */
}
for (i = 0; i < R_IMF_EXR_CODEC_MAX; i++) {
@@ -2102,7 +2102,7 @@ static char *rna_TransformOrientationSlot_path(PointerRNA *ptr)
}
}
- /* Should not happen, but in case, just return defqult path. */
+ /* Should not happen, but in case, just return default path. */
BLI_assert(0);
return BLI_strdup("transform_orientation_slots[0]");
}
@@ -7712,7 +7712,7 @@ void RNA_def_scene(BlenderRNA *brna)
prop, "Preview Range End Frame", "Alternative end frame for UI playback");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
- /* Subframe for moblur debug. */
+ /* Sub-frame for motion-blur debug. */
prop = RNA_def_property(srna, "show_subframe", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "r.flag", SCER_SHOW_SUBFRAME);
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 08387077cea..4481555b931 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -896,7 +896,7 @@ static void rna_def_gp_paint(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_GpPaint_path");
RNA_def_struct_ui_text(srna, "Grease Pencil Paint", "");
- /* Use vertex color (main swith). */
+ /* Use vertex color (main switch). */
prop = RNA_def_property(srna, "color_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, rna_enum_gpencil_paint_mode);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 251845ee5b0..c56ddeb9053 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -439,7 +439,7 @@ const EnumPropertyItem rna_enum_clip_editor_mode_items[] = {
{0, NULL, 0, NULL, NULL},
};
-/* Actually populated dynamically trough a function,
+/* Actually populated dynamically through a function,
* but helps for context-less access (e.g. doc, i18n...). */
static const EnumPropertyItem buttons_context_items[] = {
{BCONTEXT_TOOL, "TOOL", ICON_TOOL_SETTINGS, "Tool", "Active Tool and Workspace settings"},
@@ -2279,6 +2279,20 @@ static bool rna_SpaceNodeEditor_tree_type_poll(void *Cv, bNodeTreeType *type)
}
}
+static void rna_SpaceNodeEditor_cursor_location_get(PointerRNA *ptr, float value[2])
+{
+ const SpaceNode *snode = (SpaceNode *)ptr->data;
+
+ ED_node_cursor_location_get(snode, value);
+}
+
+static void rna_SpaceNodeEditor_cursor_location_set(PointerRNA *ptr, const float value[2])
+{
+ SpaceNode *snode = (SpaceNode *)ptr->data;
+
+ ED_node_cursor_location_set(snode, value);
+}
+
const EnumPropertyItem *RNA_enum_node_tree_types_itemf_impl(bContext *C, bool *r_free)
{
return rna_node_tree_type_itemf(C, rna_SpaceNodeEditor_tree_type_poll, r_free);
@@ -2346,9 +2360,13 @@ static void rna_SpaceNodeEditor_cursor_location_from_region(SpaceNode *snode,
{
ARegion *region = CTX_wm_region(C);
- UI_view2d_region_to_view(&region->v2d, x, y, &snode->cursor[0], &snode->cursor[1]);
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ float cursor_location[2];
+
+ UI_view2d_region_to_view(&region->v2d, x, y, &cursor_location[0], &cursor_location[1]);
+ cursor_location[0] /= UI_DPI_FAC;
+ cursor_location[1] /= UI_DPI_FAC;
+
+ ED_node_cursor_location_set(snode, cursor_location);
}
static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr,
@@ -2460,7 +2478,7 @@ static void rna_FileSelectPrams_filter_glob_set(PointerRNA *ptr, const char *val
BLI_strncpy(params->filter_glob, value, sizeof(params->filter_glob));
- /* Remove stupi things like last group being a wildcard-only one... */
+ /* Remove stupid things like last group being a wildcard-only one. */
BLI_path_extension_glob_validate(params->filter_glob);
}
@@ -4640,7 +4658,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
}
}
- /* Heper for drawing the icon. */
+ /* Helper for drawing the icon. */
prop = RNA_def_property(srna, "icon_from_show_object_viewport", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(
prop, "rna_SpaceView3D_icon_from_show_object_viewport_get", NULL, NULL);
@@ -5684,13 +5702,13 @@ static void rna_def_space_graph(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pivot Point", "Pivot center for rotation/scaling");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
- /* dopesheet */
+ /* Dope-sheet. */
prop = RNA_def_property(srna, "dopesheet", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "DopeSheet");
RNA_def_property_pointer_sdna(prop, NULL, "ads");
RNA_def_property_ui_text(prop, "Dope Sheet", "Settings for filtering animation data");
- /* autosnap */
+ /* Auto-snap. */
prop = RNA_def_property(srna, "auto_snap", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "autosnap");
RNA_def_property_enum_items(prop, autosnap_items);
@@ -5698,14 +5716,14 @@ static void rna_def_space_graph(BlenderRNA *brna)
prop, "Auto Snap", "Automatic time snapping settings for transformations");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
- /* readonly state info */
+ /* Read-only state info. */
prop = RNA_def_property(srna, "has_ghost_curves", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_SpaceGraphEditor_has_ghost_curves_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(
prop, "Has Ghost Curves", "Graph Editor instance has some ghost curves stored");
- /* nromalize curves */
+ /* Normalize curves. */
prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_NORMALIZE);
RNA_def_property_ui_text(prop,
@@ -6818,11 +6836,13 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_enum_items(prop, backdrop_channels_items);
RNA_def_property_ui_text(prop, "Display Channels", "Channels of the image to draw");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
-
/* the mx/my "cursor" in the node editor is used only by operators to store the mouse position */
prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 2);
- RNA_def_property_float_sdna(prop, NULL, "cursor");
+ RNA_def_property_float_funcs(prop,
+ "rna_SpaceNodeEditor_cursor_location_get",
+ "rna_SpaceNodeEditor_cursor_location_set",
+ NULL);
RNA_def_property_ui_text(prop, "Cursor Location", "Location for adding new nodes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 1870c660efd..bcf75fb284f 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -976,22 +976,6 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, cleanup_items);
RNA_def_property_ui_text(prop, "Action", "Cleanup action to execute");
- /* ** default tracker settings ** */
- prop = RNA_def_property(srna, "show_default_expanded", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED);
- RNA_def_property_ui_text(
- prop, "Show Expanded", "Show default options expanded in the user interface");
- RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
-
- /* ** extra tracker settings ** */
- prop = RNA_def_property(srna, "show_extra_expanded", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_SETTINGS_SHOW_EXTRA_EXPANDED);
- RNA_def_property_ui_text(
- prop, "Show Expanded", "Show extra options expanded in the user interface");
- RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
-
/* solver settings */
prop = RNA_def_property(srna, "use_tripod_solver", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index cfcd9aff759..1d3a7750c39 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -649,7 +649,7 @@ static StructRNA *rna_UIList_register(Main *bmain,
uiList dummyuilist = {NULL};
PointerRNA dummyul_ptr;
int have_function[3];
- size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
+ size_t over_alloc = 0; /* Warning, if this becomes a mess, we better do another allocation. */
/* setup dummy menu & menu type to store static properties in */
dummyuilist.type = &dummyult;
@@ -669,7 +669,7 @@ static StructRNA *rna_UIList_register(Main *bmain,
return NULL;
}
- /* check if we have registered this uilist type before, and remove it */
+ /* Check if we have registered this UI-list type before, and remove it. */
ult = WM_uilisttype_find(dummyult.idname, true);
if (ult && ult->rna_ext.srna) {
rna_UIList_unregister(bmain, ult->rna_ext.srna);
@@ -904,7 +904,7 @@ static StructRNA *rna_Menu_register(Main *bmain,
Menu dummymenu = {NULL};
PointerRNA dummymtr;
int have_function[2];
- size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
+ size_t over_alloc = 0; /* Warning, if this becomes a mess, we better do another allocation. */
size_t description_size = 0;
char _menu_descr[RNA_DYN_DESCR_MAX];
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 447f5b4210b..f128719db19 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -595,7 +595,7 @@ static const char *rna_ui_get_enum_name(bContext *C,
const char *identifier)
{
PropertyRNA *prop = NULL;
- const EnumPropertyItem *items = NULL, *item;
+ const EnumPropertyItem *items = NULL;
bool free;
const char *name = "";
@@ -609,11 +609,9 @@ static const char *rna_ui_get_enum_name(bContext *C,
RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free);
if (items) {
- for (item = items; item->identifier; item++) {
- if (item->identifier[0] && STREQ(item->identifier, identifier)) {
- name = item->name;
- break;
- }
+ const int index = RNA_enum_from_identifier(items, identifier);
+ if (index != -1) {
+ name = items[index].name;
}
if (free) {
MEM_freeN((void *)items);
@@ -629,7 +627,7 @@ static const char *rna_ui_get_enum_description(bContext *C,
const char *identifier)
{
PropertyRNA *prop = NULL;
- const EnumPropertyItem *items = NULL, *item;
+ const EnumPropertyItem *items = NULL;
bool free;
const char *desc = "";
@@ -643,11 +641,9 @@ static const char *rna_ui_get_enum_description(bContext *C,
RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free);
if (items) {
- for (item = items; item->identifier; item++) {
- if (item->identifier[0] && STREQ(item->identifier, identifier)) {
- desc = item->description;
- break;
- }
+ const int index = RNA_enum_from_identifier(items, identifier);
+ if (index != -1) {
+ desc = items[index].description;
}
if (free) {
MEM_freeN((void *)items);
@@ -663,7 +659,7 @@ static int rna_ui_get_enum_icon(bContext *C,
const char *identifier)
{
PropertyRNA *prop = NULL;
- const EnumPropertyItem *items = NULL, *item;
+ const EnumPropertyItem *items = NULL;
bool free;
int icon = ICON_NONE;
@@ -677,11 +673,9 @@ static int rna_ui_get_enum_icon(bContext *C,
RNA_property_enum_items(C, ptr, prop, &items, NULL, &free);
if (items) {
- for (item = items; item->identifier; item++) {
- if (item->identifier[0] && STREQ(item->identifier, identifier)) {
- icon = item->icon;
- break;
- }
+ const int index = RNA_enum_from_identifier(items, identifier);
+ if (index != -1) {
+ icon = items[index].icon;
}
if (free) {
MEM_freeN((void *)items);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 8a836eb7376..269a242f074 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -243,7 +243,7 @@ void rna_userdef_is_dirty_update(Main *UNUSED(bmain),
rna_userdef_is_dirty_update_impl();
}
-/** Take care not to use this if we expet 'is_dirty' to be tagged. */
+/** Take care not to use this if we expect 'is_dirty' to be tagged. */
static void rna_userdef_ui_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *UNUSED(ptr))
@@ -863,7 +863,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain,
PointerRNA dummy_ptr;
// int have_function[1];
- /* setup dummy addon-pref & addon-pref type to store static properties in */
+ /* Setup dummy add-on preference and it's type to store static properties in. */
RNA_pointer_create(NULL, &RNA_AddonPreferences, &dummy_addon, &dummy_ptr);
/* validate the python class */
@@ -881,13 +881,13 @@ static StructRNA *rna_AddonPref_register(Main *bmain,
return NULL;
}
- /* check if we have registered this addon-pref type before, and remove it */
+ /* Check if we have registered this add-on preference type before, and remove it. */
apt = BKE_addon_pref_type_find(dummy_addon.module, true);
if (apt && apt->rna_ext.srna) {
rna_AddonPref_unregister(bmain, apt->rna_ext.srna);
}
- /* create a new addon-pref type */
+ /* Create a new add-on preference type. */
apt = MEM_mallocN(sizeof(bAddonPrefType), "addonpreftype");
memcpy(apt, &dummy_apt, sizeof(dummy_apt));
BKE_addon_pref_type_add(apt);
@@ -4762,6 +4762,11 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Gizmo Size", "Diameter of the gizmo");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ prop = RNA_def_property(srna, "gizmo_size_navigate_v3d", PROP_INT, PROP_PIXEL);
+ RNA_def_property_range(prop, 30, 200);
+ RNA_def_property_ui_text(prop, "Navigate Gizmo Size", "The Navigate Gizmo size");
+ RNA_def_property_update(prop, 0, "rna_userdef_gizmo_update");
+
/* Lookdev */
prop = RNA_def_property(srna, "lookdev_sphere_size", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "lookdev_sphere_size");
@@ -5649,7 +5654,7 @@ static void rna_def_userdef_input(BlenderRNA *brna)
};
static const EnumPropertyItem view_zoom_styles[] = {
- {USER_ZOOM_CONT,
+ {USER_ZOOM_CONTINUE,
"CONTINUE",
0,
"Continue",
@@ -5734,10 +5739,11 @@ static void rna_def_userdef_input(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_mouse_continuous", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_CONTINUOUS_MOUSE);
- RNA_def_property_ui_text(prop,
- "Continuous Grab",
- "Allow moving the mouse outside the view on some manipulations "
- "(transform, ui control drag)");
+ RNA_def_property_ui_text(
+ prop,
+ "Continuous Grab",
+ "Let the mouse wrap around the view boundaries so mouse movements are not limited by the "
+ "screen size (used by transform, dragging of UI controls, etc.)");
prop = RNA_def_property(srna, "use_drag_immediately", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_RELEASECONFIRM);
diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c
index a98a52c2252..214a32372dd 100644
--- a/source/blender/makesrna/intern/rna_vfont.c
+++ b/source/blender/makesrna/intern/rna_vfont.c
@@ -37,7 +37,7 @@
# include "WM_api.h"
-/* matching fnction in rna_ID.c */
+/* Matching function in rna_ID.c */
static int rna_VectorFont_filepath_editable(PointerRNA *ptr, const char **UNUSED(r_info))
{
VFont *vfont = (VFont *)ptr->owner_id;
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index 3ebcb09a65d..6b96562b3f8 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -72,6 +72,12 @@ const EnumPropertyItem rna_enum_window_cursor_items[] = {
# include "WM_types.h"
+/* Needed since RNA doesn't use `const` in function signatures. */
+static bool rna_KeyMapItem_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2)
+{
+ return WM_keymap_item_compare(k1, k2);
+}
+
static void rna_KeyMapItem_to_string(wmKeyMapItem *kmi, bool compact, char *result)
{
WM_keymap_item_to_string(kmi, compact, result, UI_MAX_SHORTCUT_STR);
@@ -156,7 +162,7 @@ static void rna_gizmo_group_type_unlink_delayed(ReportList *reports, const char
}
}
-/* placeholder data for final implementation of a true progressbar */
+/* Placeholder data for final implementation of a true progress-bar. */
static struct wmStaticProgress {
float min;
float max;
@@ -1103,7 +1109,7 @@ void RNA_api_keymapitem(StructRNA *srna)
FunctionRNA *func;
PropertyRNA *parm;
- func = RNA_def_function(srna, "compare", "WM_keymap_item_compare");
+ func = RNA_def_function(srna, "compare", "rna_KeyMapItem_compare");
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_boolean(func, "result", 0, "Comparison result", "");
diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c
index 00d832e2eef..e61482c91e2 100644
--- a/source/blender/makesrna/intern/rna_wm_gizmo.c
+++ b/source/blender/makesrna/intern/rna_wm_gizmo.c
@@ -260,7 +260,7 @@ static wmGizmo *rna_GizmoProperties_find_operator(PointerRNA *ptr)
wmWindowManager *wm = (wmWindowManager *)ptr->owner_id;
# endif
- /* We could try workaruond this lookup, but not trivial. */
+ /* We could try workaround this lookup, but not trivial. */
for (bScreen *screen = G_MAIN->screens.first; screen; screen = screen->id.next) {
IDProperty *properties = ptr->data;
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
@@ -1089,7 +1089,7 @@ static void rna_def_gizmo(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_pointer(func, "event", "Event", "", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
- /* TODO, shuold be a enum-flag */
+ /* TODO, should be a enum-flag */
parm = RNA_def_enum_flag(func, "tweak", tweak_actions, 0, "Tweak", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_enum_flag(
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 3a7addcba94..c19782df44b 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -185,7 +185,7 @@ endif()
if(WITH_OPENVDB)
list(APPEND INC
- ../../../intern/openvdb
+ ../../../intern/openvdb
)
list(APPEND INC_SYS
${OPENVDB_INCLUDE_DIRS}
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 412d6b87d82..b48bf722526 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -68,7 +68,8 @@ static void initData(ModifierData *md)
MEMCPY_STRUCT_AFTER(amd, DNA_struct_default_get(ArrayModifierData), modifier);
- /* Open the first subpanel by default, it corresspnds to Relative offset which is enabled too. */
+ /* Open the first sub-panel by default,
+ * it corresponds to Relative offset which is enabled too. */
md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1;
}
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index 04b68a7a800..e72e0279263 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -222,7 +222,7 @@ static void deformVerts(ModifierData *md,
}
}
- /* happens on file load (ONLY when i decomment changes in readfile.c) */
+ /* Happens on file load (ONLY when I un-comment changes in readfile.c) */
if (!collmd->bvhtree) {
collmd->bvhtree = bvhtree_build_from_mvert(
collmd->current_x, collmd->tri, collmd->tri_num, ob->pd->pdef_sboft);
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index 15c4e8af6ce..001c7d8d098 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -423,11 +423,11 @@ static void calc_tangent_ortho(float ts[3][3])
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);
- /* orthognalise tangent */
+ /* 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);
- /* orthognalise bitangent */
+ /* 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);
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index f3d6cf49dd6..23bfe76a5c3 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -215,24 +215,27 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
class GeometryNodesEvaluator {
private:
blender::LinearAllocator<> allocator_;
- Map<const DInputSocket *, GMutablePointer> value_by_input_;
+ Map<std::pair<const DInputSocket *, const DOutputSocket *>, GMutablePointer> value_by_input_;
Vector<const DInputSocket *> group_outputs_;
blender::nodes::MultiFunctionByNode &mf_by_node_;
const blender::nodes::DataTypeConversions &conversions_;
const PersistentDataHandleMap &handle_map_;
const Object *self_object_;
+ Depsgraph *depsgraph_;
public:
GeometryNodesEvaluator(const Map<const DOutputSocket *, GMutablePointer> &group_input_data,
Vector<const DInputSocket *> group_outputs,
blender::nodes::MultiFunctionByNode &mf_by_node,
const PersistentDataHandleMap &handle_map,
- const Object *self_object)
+ const Object *self_object,
+ Depsgraph *depsgraph)
: group_outputs_(std::move(group_outputs)),
mf_by_node_(mf_by_node),
conversions_(blender::nodes::get_implicit_type_conversions()),
handle_map_(handle_map),
- self_object_(self_object)
+ self_object_(self_object),
+ depsgraph_(depsgraph)
{
for (auto item : group_input_data.items()) {
this->forward_to_inputs(*item.key, item.value);
@@ -243,8 +246,8 @@ class GeometryNodesEvaluator {
{
Vector<GMutablePointer> results;
for (const DInputSocket *group_output : group_outputs_) {
- GMutablePointer result = this->get_input_value(*group_output);
- results.append(result);
+ Vector<GMutablePointer> result = this->get_input_values(*group_output);
+ results.append(result[0]);
}
for (GMutablePointer value : value_by_input_.values()) {
value.destruct();
@@ -253,32 +256,53 @@ class GeometryNodesEvaluator {
}
private:
- GMutablePointer get_input_value(const DInputSocket &socket_to_compute)
+ Vector<GMutablePointer> get_input_values(const DInputSocket &socket_to_compute)
{
- std::optional<GMutablePointer> value = value_by_input_.pop_try(&socket_to_compute);
- if (value.has_value()) {
- /* This input has been computed before, return it directly. */
- return *value;
- }
Span<const DOutputSocket *> from_sockets = socket_to_compute.linked_sockets();
Span<const DGroupInput *> from_group_inputs = socket_to_compute.linked_group_inputs();
const int total_inputs = from_sockets.size() + from_group_inputs.size();
- BLI_assert(total_inputs <= 1);
if (total_inputs == 0) {
/* The input is not connected, use the value from the socket itself. */
- return get_unlinked_input_value(socket_to_compute);
+ return {get_unlinked_input_value(socket_to_compute)};
}
+
if (from_group_inputs.size() == 1) {
- /* The input gets its value from the input of a group that is not further connected. */
- return get_unlinked_input_value(socket_to_compute);
+ return {get_unlinked_input_value(socket_to_compute)};
+ }
+
+ /* Multi-input sockets contain a vector of inputs. */
+ if (socket_to_compute.is_multi_input_socket()) {
+ Vector<GMutablePointer> values;
+ for (const DOutputSocket *from_socket : from_sockets) {
+ const std::pair<const DInputSocket *, const DOutputSocket *> key = std::make_pair(
+ &socket_to_compute, from_socket);
+ std::optional<GMutablePointer> value = value_by_input_.pop_try(key);
+ if (value.has_value()) {
+ values.append(*value);
+ }
+ else {
+ this->compute_output_and_forward(*from_socket);
+ GMutablePointer value = value_by_input_.pop(key);
+ values.append(value);
+ }
+ }
+ return values;
}
- /* Compute the socket now. */
const DOutputSocket &from_socket = *from_sockets[0];
+ const std::pair<const DInputSocket *, const DOutputSocket *> key = std::make_pair(
+ &socket_to_compute, &from_socket);
+ std::optional<GMutablePointer> value = value_by_input_.pop_try(key);
+ if (value.has_value()) {
+ /* This input has been computed before, return it directly. */
+ return {*value};
+ }
+
+ /* Compute the socket now. */
this->compute_output_and_forward(from_socket);
- return value_by_input_.pop(&socket_to_compute);
+ return {value_by_input_.pop(key)};
}
void compute_output_and_forward(const DOutputSocket &socket_to_compute)
@@ -299,14 +323,21 @@ class GeometryNodesEvaluator {
GValueMap<StringRef> node_inputs_map{allocator_};
for (const DInputSocket *input_socket : node.inputs()) {
if (input_socket->is_available()) {
- GMutablePointer value = this->get_input_value(*input_socket);
- node_inputs_map.add_new_direct(input_socket->identifier(), value);
+ Vector<GMutablePointer> values = this->get_input_values(*input_socket);
+ for (int i = 0; i < values.size(); ++i) {
+ /* Values from Multi Input Sockets are stored in input map with the format
+ * <identifier>[<index>]. */
+ blender::StringRefNull key = allocator_.copy_string(
+ input_socket->identifier() + (i > 0 ? ("[" + std::to_string(i)) + "]" : ""));
+ node_inputs_map.add_new_direct(key, std::move(values[i]));
+ }
}
}
/* Execute the node. */
GValueMap<StringRef> node_outputs_map{allocator_};
- GeoNodeExecParams params{bnode, node_inputs_map, node_outputs_map, handle_map_, self_object_};
+ GeoNodeExecParams params{
+ bnode, node_inputs_map, node_outputs_map, handle_map_, self_object_, depsgraph_};
this->execute_node(node, params);
/* Forward computed outputs to linked input sockets. */
@@ -389,13 +420,15 @@ class GeometryNodesEvaluator {
void forward_to_inputs(const DOutputSocket &from_socket, GMutablePointer value_to_forward)
{
+ /* For all sockets that are linked with the from_socket push the value to their node. */
Span<const DInputSocket *> to_sockets_all = from_socket.linked_sockets();
const CPPType &from_type = *value_to_forward.type();
-
Vector<const DInputSocket *> to_sockets_same_type;
for (const DInputSocket *to_socket : to_sockets_all) {
const CPPType &to_type = *blender::nodes::socket_cpp_type_get(*to_socket->typeinfo());
+ const std::pair<const DInputSocket *, const DOutputSocket *> key = std::make_pair(
+ to_socket, &from_socket);
if (from_type == to_type) {
to_sockets_same_type.append(to_socket);
}
@@ -407,7 +440,7 @@ class GeometryNodesEvaluator {
else {
to_type.copy_to_uninitialized(to_type.default_value(), buffer);
}
- value_by_input_.add_new(to_socket, GMutablePointer{to_type, buffer});
+ add_value_to_input_socket(key, GMutablePointer{to_type, buffer});
}
}
@@ -418,23 +451,35 @@ class GeometryNodesEvaluator {
else if (to_sockets_same_type.size() == 1) {
/* This value is only used on one input socket, no need to copy it. */
const DInputSocket *to_socket = to_sockets_same_type[0];
- value_by_input_.add_new(to_socket, value_to_forward);
+ const std::pair<const DInputSocket *, const DOutputSocket *> key = std::make_pair(
+ to_socket, &from_socket);
+
+ add_value_to_input_socket(key, value_to_forward);
}
else {
/* Multiple inputs use the value, make a copy for every input except for one. */
const DInputSocket *first_to_socket = to_sockets_same_type[0];
Span<const DInputSocket *> other_to_sockets = to_sockets_same_type.as_span().drop_front(1);
const CPPType &type = *value_to_forward.type();
-
- value_by_input_.add_new(first_to_socket, value_to_forward);
+ const std::pair<const DInputSocket *, const DOutputSocket *> first_key = std::make_pair(
+ first_to_socket, &from_socket);
+ add_value_to_input_socket(first_key, value_to_forward);
for (const DInputSocket *to_socket : other_to_sockets) {
+ const std::pair<const DInputSocket *, const DOutputSocket *> key = std::make_pair(
+ to_socket, &from_socket);
void *buffer = allocator_.allocate(type.size(), type.alignment());
type.copy_to_uninitialized(value_to_forward.get(), buffer);
- value_by_input_.add_new(to_socket, GMutablePointer{type, buffer});
+ add_value_to_input_socket(key, GMutablePointer{type, buffer});
}
}
}
+ void add_value_to_input_socket(const std::pair<const DInputSocket *, const DOutputSocket *> key,
+ GMutablePointer value)
+ {
+ value_by_input_.add_new(key, value);
+ }
+
GMutablePointer get_unlinked_input_value(const DInputSocket &socket)
{
bNodeSocket *bsocket;
@@ -473,7 +518,7 @@ class GeometryNodesEvaluator {
* TODO(Hans): Codify this with some sort of table or refactor IDProperty use in RNA_access.c.
*/
struct SocketPropertyType {
- /* Create the actual propery used to store the data for the modifier. */
+ /* Create the actual property used to store the data for the modifier. */
IDProperty *(*create_prop)(const bNodeSocket &socket, const char *name);
/* Reused to build the "soft_min" property too. */
IDProperty *(*create_min_ui_prop)(const bNodeSocket &socket, const char *name);
@@ -926,7 +971,7 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
group_outputs.append(&socket_to_compute);
GeometryNodesEvaluator evaluator{
- group_inputs, group_outputs, mf_by_node, handle_map, ctx->object};
+ group_inputs, group_outputs, mf_by_node, handle_map, ctx->object, ctx->depsgraph};
Vector<GMutablePointer> results = evaluator.execute();
BLI_assert(results.size() == 1);
GMutablePointer result = results[0];
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index ba370b401f3..84360caa345 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -486,9 +486,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/*
* Normal Calculation (for face flipping)
* Sort edge verts for correct face flipping
- * NOT REALLY NEEDED but face flipping is nice.
- *
- * */
+ * NOT REALLY NEEDED but face flipping is nice. */
/* Notice!
*
@@ -780,7 +778,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
* use edge connectivity work this out */
if (SV_IS_VALID(vc->v[0])) {
if (SV_IS_VALID(vc->v[1])) {
- /* 2 edges connedted */
+ /* 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);
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index e41e70864dc..ea31bdc6e31 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -256,7 +256,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
smd->limit[0] = min_ff(smd->limit[0], smd->limit[1]); /* Upper limit >= than lower limit */
- /* Calculate matrixs do convert between coordinate spaces */
+ /* Calculate matrix to convert between coordinate spaces. */
if (smd->origin != NULL) {
transf = &tmp_transf;
BLI_SPACE_TRANSFORM_SETUP(transf, ob, smd->origin);
@@ -314,7 +314,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
simpleDeform_callback = simpleDeform_stretch;
break;
default:
- return; /* No simpledeform mode? */
+ return; /* No simple-deform mode? */
}
if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) {
diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
index f62980ec4fd..0f8503eddde 100644
--- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
+++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
@@ -2434,9 +2434,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
vm[orig_mloop[loopstart + j].v]);
BLI_assert(flip ||
vm[orig_medge[new_edge->old_edge].v1] == vm[orig_mloop[loopstart + j].v]);
- /* The vert thats in the current loop. */
+ /* The vert that's in the current loop. */
const uint new_v1 = new_edge->link_edge_groups[flip]->new_vert;
- /* The vert thats in the next loop. */
+ /* The vert that's in the next loop. */
const uint new_v2 = new_edge->link_edge_groups[1 - flip]->new_vert;
if (k == 0 || face_verts[k - 1] != new_v1) {
face_loops[k] = loopstart + j;
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 0fad78683eb..99011c5e351 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -104,7 +104,7 @@ typedef struct SDefBindCalcData {
* needed once when running bind, so optimizing this structure isn't a priority.
*/
typedef struct SDefBindPoly {
- /** Coordinates copied directly from the modifiers inptut. */
+ /** Coordinates copied directly from the modifiers input. */
float (*coords)[3];
/** Coordinates projected into 2D space using `normal`. */
float (*coords_v2)[2];
@@ -114,7 +114,12 @@ typedef struct SDefBindPoly {
float weight_dist_proj;
float weight_dist;
float weight;
+ /** Distances from the centroid to edges flanking the corner vertex, used to penalize
+ * small or long and narrow faces in favor of bigger and more square ones. */
float scales[2];
+ /** Distance weight from the corner vertex to the chord line, used to penalize
+ * cases with the three consecutive vertices being nearly in line. */
+ float scale_mid;
/** Center of `coords` */
float centroid[3];
/** Center of `coords_v2` */
@@ -123,15 +128,18 @@ typedef struct SDefBindPoly {
* The calculated normal of coords (could be shared between faces).
*/
float normal[3];
+ /** Vectors pointing from the centroid to the midpoints of the two edges
+ * flanking the corner vertex. */
float cent_edgemid_vecs_v2[2][2];
- /**
- * The unsigned angle of this face-corner in `[0.0 .. PI]` range,
- * where a small value is a thin corner. PI is a straight line.
- * Take care dividing by this value as it can approach zero.
- */
+ /** Angle between the cent_edgemid_vecs_v2 vectors. */
float edgemid_angle;
+ /** Angles between the centroid-to-point and cent_edgemid_vecs_v2 vectors.
+ * Positive values measured towards the corner; clamped non-negative. */
float point_edgemid_angles[2];
+ /** Angles between the centroid-to-corner and cent_edgemid_vecs_v2 vectors. */
float corner_edgemid_angles[2];
+ /** Weight of the bind mode based on the corner and two adjacent vertices,
+ * versus the one based on the centroid and the dominant edge. */
float dominant_angle_weight;
/** Index of the input polygon. */
uint index;
@@ -414,13 +422,14 @@ BLI_INLINE uint nearestVert(SDefBindCalcData *const data, const float point_co[3
BLI_INLINE int isPolyValid(const float coords[][2], const uint nr)
{
- float prev_co[2];
+ float prev_co[2], prev_prev_co[2];
float curr_vec[2], prev_vec[2];
if (!is_poly_convex_v2(coords, nr)) {
return MOD_SDEF_BIND_RESULT_CONCAVE_ERR;
}
+ copy_v2_v2(prev_prev_co, coords[nr - 2]);
copy_v2_v2(prev_co, coords[nr - 1]);
sub_v2_v2v2(prev_vec, prev_co, coords[nr - 2]);
normalize_v2(prev_vec);
@@ -428,15 +437,23 @@ BLI_INLINE int isPolyValid(const float coords[][2], const uint nr)
for (int i = 0; i < nr; i++) {
sub_v2_v2v2(curr_vec, coords[i], prev_co);
+ /* Check overlap between directly adjacent vertices. */
const float curr_len = normalize_v2(curr_vec);
if (curr_len < FLT_EPSILON) {
return MOD_SDEF_BIND_RESULT_OVERLAP_ERR;
}
+ /* Check overlap between vertices skipping one. */
+ if (len_squared_v2v2(prev_prev_co, coords[i]) < FLT_EPSILON * FLT_EPSILON) {
+ return MOD_SDEF_BIND_RESULT_OVERLAP_ERR;
+ }
+
+ /* Check for adjacent parallel edges. */
if (1.0f - dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) {
return MOD_SDEF_BIND_RESULT_CONCAVE_ERR;
}
+ copy_v2_v2(prev_prev_co, prev_co);
copy_v2_v2(prev_co, coords[i]);
copy_v2_v2(prev_vec, curr_vec);
}
@@ -460,9 +477,9 @@ static void freeBindData(SDefBindWeightData *const bwdata)
MEM_freeN(bwdata);
}
-BLI_INLINE float computeAngularWeight(const float point_angle)
+BLI_INLINE float computeAngularWeight(const float point_angle, const float edgemid_angle)
{
- return sinf(point_angle * M_PI_2);
+ return sinf(min_ff(point_angle / edgemid_angle, 1) * M_PI_2);
}
BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
@@ -603,33 +620,51 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
avg_point_dist += bpoly->weight_dist;
- /* Compute centroid to mid-edge vectors */
- mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[0],
- bpoly->coords_v2[bpoly->edge_vert_inds[0]],
- bpoly->coords_v2[bpoly->corner_ind]);
+ /* Common vertex coordinates. */
+ const float *const vert0_v2 = bpoly->coords_v2[bpoly->edge_vert_inds[0]];
+ const float *const vert1_v2 = bpoly->coords_v2[bpoly->edge_vert_inds[1]];
+ const float *const corner_v2 = bpoly->coords_v2[bpoly->corner_ind];
- mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[1],
- bpoly->coords_v2[bpoly->edge_vert_inds[1]],
- bpoly->coords_v2[bpoly->corner_ind]);
+ /* Compute centroid to mid-edge vectors */
+ mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[0], vert0_v2, corner_v2);
+ mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[1], vert1_v2, corner_v2);
sub_v2_v2(bpoly->cent_edgemid_vecs_v2[0], bpoly->centroid_v2);
sub_v2_v2(bpoly->cent_edgemid_vecs_v2[1], bpoly->centroid_v2);
- /* Compute poly scales with respect to mid-edges, and normalize the vectors */
- bpoly->scales[0] = normalize_v2(bpoly->cent_edgemid_vecs_v2[0]);
- bpoly->scales[1] = normalize_v2(bpoly->cent_edgemid_vecs_v2[1]);
+ normalize_v2(bpoly->cent_edgemid_vecs_v2[0]);
+ normalize_v2(bpoly->cent_edgemid_vecs_v2[1]);
- /* Compute the required polygon angles */
+ /* Compute poly scales with respect to the two edges. */
+ bpoly->scales[0] = dist_to_line_v2(bpoly->centroid_v2, vert0_v2, corner_v2);
+ bpoly->scales[1] = dist_to_line_v2(bpoly->centroid_v2, vert1_v2, corner_v2);
+
+ /* Compute the angle between the edge mid vectors. */
bpoly->edgemid_angle = angle_normalized_v2v2(bpoly->cent_edgemid_vecs_v2[0],
bpoly->cent_edgemid_vecs_v2[1]);
- sub_v2_v2v2(tmp_vec_v2, bpoly->coords_v2[bpoly->corner_ind], bpoly->centroid_v2);
+ /* Compute the angles between the corner and the edge mid vectors. The angles
+ * are computed signed in order to correctly clamp point_edgemid_angles later. */
+ float corner_angles[2];
+
+ sub_v2_v2v2(tmp_vec_v2, corner_v2, bpoly->centroid_v2);
normalize_v2(tmp_vec_v2);
- bpoly->corner_edgemid_angles[0] = angle_normalized_v2v2(tmp_vec_v2,
- bpoly->cent_edgemid_vecs_v2[0]);
- bpoly->corner_edgemid_angles[1] = angle_normalized_v2v2(tmp_vec_v2,
- bpoly->cent_edgemid_vecs_v2[1]);
+ corner_angles[0] = angle_signed_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[0]);
+ corner_angles[1] = angle_signed_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[1]);
+
+ bpoly->corner_edgemid_angles[0] = fabsf(corner_angles[0]);
+ bpoly->corner_edgemid_angles[1] = fabsf(corner_angles[1]);
+
+ /* Verify that the computed values are valid (the polygon isn't somehow
+ * degenerate despite having passed isPolyValid). */
+ if (bpoly->scales[0] < FLT_EPSILON || bpoly->scales[1] < FLT_EPSILON ||
+ bpoly->edgemid_angle < FLT_EPSILON || bpoly->corner_edgemid_angles[0] < FLT_EPSILON ||
+ bpoly->corner_edgemid_angles[1] < FLT_EPSILON) {
+ freeBindData(bwdata);
+ data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
+ return NULL;
+ }
/* Check for infinite weights, and compute angular data otherwise. */
if (bpoly->weight_dist < FLT_EPSILON) {
@@ -640,15 +675,54 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
}
else {
- float cent_point_vec[2];
+ /* Compute angles between the point and the edge mid vectors. */
+ float cent_point_vec[2], point_angles[2];
sub_v2_v2v2(cent_point_vec, bpoly->point_v2, bpoly->centroid_v2);
normalize_v2(cent_point_vec);
- bpoly->point_edgemid_angles[0] = angle_normalized_v2v2(cent_point_vec,
- bpoly->cent_edgemid_vecs_v2[0]);
- bpoly->point_edgemid_angles[1] = angle_normalized_v2v2(cent_point_vec,
- bpoly->cent_edgemid_vecs_v2[1]);
+ point_angles[0] = angle_signed_v2v2(cent_point_vec, bpoly->cent_edgemid_vecs_v2[0]) *
+ signf(corner_angles[0]);
+ point_angles[1] = angle_signed_v2v2(cent_point_vec, bpoly->cent_edgemid_vecs_v2[1]) *
+ signf(corner_angles[1]);
+
+ if (point_angles[0] <= 0 && point_angles[1] <= 0) {
+ /* If the point is outside the corner formed by the edge mid vectors,
+ * choose to clamp the closest side and flip the other. */
+ if (point_angles[0] < point_angles[1]) {
+ point_angles[0] = bpoly->edgemid_angle - point_angles[1];
+ }
+ else {
+ point_angles[1] = bpoly->edgemid_angle - point_angles[0];
+ }
+ }
+
+ bpoly->point_edgemid_angles[0] = max_ff(0, point_angles[0]);
+ bpoly->point_edgemid_angles[1] = max_ff(0, point_angles[1]);
+
+ /* Compute the distance scale for the corner. The base value is the orthogonal
+ * distance from the corner to the chord, scaled by sqrt(2) to preserve the old
+ * values in case of a square grid. This doesn't use the centroid because the
+ * LOOPTRI method only uses these three vertices. */
+ bpoly->scale_mid = area_tri_v2(vert0_v2, corner_v2, vert1_v2) /
+ len_v2v2(vert0_v2, vert1_v2) * sqrtf(2);
+
+ if (bpoly->inside) {
+ /* When inside, interpolate to centroid-based scale close to the center. */
+ float min_dist = min_ff(bpoly->scales[0], bpoly->scales[1]);
+
+ bpoly->scale_mid = interpf(bpoly->scale_mid,
+ (bpoly->scales[0] + bpoly->scales[1]) / 2,
+ min_ff(bpoly->weight_dist_proj / min_dist, 1));
+ }
+
+ /* Verify that the additional computed values are valid. */
+ if (bpoly->scale_mid < FLT_EPSILON ||
+ bpoly->point_edgemid_angles[0] + bpoly->point_edgemid_angles[1] < FLT_EPSILON) {
+ freeBindData(bwdata);
+ data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
+ return NULL;
+ }
}
}
}
@@ -688,12 +762,15 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
/* Compute angular weight component */
if (epolys->num == 1) {
- ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]);
+ ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
+ bpolys[0]->edgemid_angle);
bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[0];
}
else if (epolys->num == 2) {
- ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]);
- ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]]);
+ ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
+ bpolys[0]->edgemid_angle);
+ ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]],
+ bpolys[1]->edgemid_angle);
bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[1];
bpolys[1]->weight_angular *= ang_weights[0] * ang_weights[1];
@@ -731,6 +808,13 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
bpoly->dominant_angle_weight = corner_angle_weights[1];
}
+ /* Check for invalid weights just in case computations fail. */
+ if (bpoly->dominant_angle_weight < 0 || bpoly->dominant_angle_weight > 1) {
+ freeBindData(bwdata);
+ data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
+ return NULL;
+ }
+
bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2);
/* Compute quadratic angular scale interpolation weight */
@@ -748,10 +832,15 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
inv_sqr *= inv_sqr;
scale_weight = sqr / (sqr + inv_sqr);
+ BLI_assert(scale_weight >= 0 && scale_weight <= 1);
+
/* Compute interpolated scale (no longer need the individual scales,
* so simply storing the result over the scale in index zero) */
- bpoly->scales[0] = bpoly->scales[bpoly->dominant_edge] * (1.0f - scale_weight) +
- bpoly->scales[!bpoly->dominant_edge] * scale_weight;
+ bpoly->scales[0] = interpf(bpoly->scale_mid,
+ interpf(bpoly->scales[!bpoly->dominant_edge],
+ bpoly->scales[bpoly->dominant_edge],
+ scale_weight),
+ bpoly->dominant_angle_weight);
/* Scale the point distance weights, and introduce falloff */
bpoly->weight_dist_proj /= bpoly->scales[0];
diff --git a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
index 941bc8409f7..41ed7ae983a 100644
--- a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
+++ b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc
@@ -24,6 +24,7 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_volume.h"
+#include "BKE_volume_to_mesh.hh"
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
@@ -128,139 +129,6 @@ static void panelRegister(ARegionType *region_type)
modifier_panel_register(region_type, eModifierType_VolumeToMesh, panel_draw);
}
-#ifdef WITH_OPENVDB
-
-struct VolumeToMeshOp {
- const openvdb::GridBase &base_grid;
- VolumeToMeshModifierData &vmmd;
- const ModifierEvalContext &ctx;
- std::vector<openvdb::Vec3s> verts;
- std::vector<openvdb::Vec3I> tris;
- std::vector<openvdb::Vec4I> quads;
-
- template<typename GridType> bool operator()()
- {
- if constexpr (std::is_scalar_v<typename GridType::ValueType>) {
- this->generate_mesh_data<GridType>();
- return true;
- }
- else {
- return false;
- }
- }
-
- template<typename GridType> void generate_mesh_data()
- {
- /* Make a new transform from the index space into the mesh object space. */
- openvdb::math::Transform::Ptr transform = this->base_grid.transform().copy();
- transform->postMult(openvdb::Mat4d((float *)vmmd.object->obmat));
- openvdb::Mat4d imat = openvdb::Mat4d((float *)ctx.object->imat);
- /* `imat` had floating point issues and wasn't affine. */
- imat.setCol(3, openvdb::Vec4d(0, 0, 0, 1));
- transform->postMult(imat);
-
- /* Create a new grid with a different transform. The underlying tree is shared. */
- typename GridType::ConstPtr grid = openvdb::gridConstPtrCast<GridType>(
- this->base_grid.copyGridReplacingTransform(transform));
-
- if (this->vmmd.resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_GRID) {
- this->grid_to_mesh(*grid);
- return;
- }
-
- const float resolution_factor = this->compute_resolution_factor(*grid);
- typename GridType::Ptr temp_grid = this->create_grid_with_changed_resolution(
- *grid, resolution_factor);
- this->grid_to_mesh(*temp_grid);
- }
-
- template<typename GridType>
- typename GridType::Ptr create_grid_with_changed_resolution(const GridType &old_grid,
- const float resolution_factor)
- {
- BLI_assert(resolution_factor > 0.0f);
-
- openvdb::Mat4R xform;
- xform.setToScale(openvdb::Vec3d(resolution_factor));
- openvdb::tools::GridTransformer transformer{xform};
-
- typename GridType::Ptr new_grid = GridType::create();
- transformer.transformGrid<openvdb::tools::BoxSampler>(old_grid, *new_grid);
- new_grid->transform() = old_grid.transform();
- new_grid->transform().preScale(1.0f / resolution_factor);
- return new_grid;
- }
-
- float compute_resolution_factor(const openvdb::GridBase &grid) const
- {
- const openvdb::Vec3s voxel_size{grid.voxelSize()};
- const float current_voxel_size = std::max({voxel_size[0], voxel_size[1], voxel_size[2]});
- const float desired_voxel_size = this->compute_desired_voxel_size(grid);
- return current_voxel_size / desired_voxel_size;
- }
-
- float compute_desired_voxel_size(const openvdb::GridBase &grid) const
- {
- if (this->vmmd.resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
- return this->vmmd.voxel_size;
- }
- const openvdb::CoordBBox coord_bbox = base_grid.evalActiveVoxelBoundingBox();
- const openvdb::BBoxd bbox = grid.transform().indexToWorld(coord_bbox);
- const float max_extent = bbox.extents()[bbox.maxExtent()];
- const float voxel_size = max_extent / this->vmmd.voxel_amount;
- return voxel_size;
- }
-
- template<typename GridType> void grid_to_mesh(const GridType &grid)
- {
- openvdb::tools::volumeToMesh(
- grid, this->verts, this->tris, this->quads, this->vmmd.threshold, this->vmmd.adaptivity);
- }
-};
-
-static Mesh *new_mesh_from_openvdb_data(Span<openvdb::Vec3s> verts,
- Span<openvdb::Vec3I> tris,
- Span<openvdb::Vec4I> quads)
-{
- const int tot_loops = 3 * tris.size() + 4 * quads.size();
- const int tot_polys = tris.size() + quads.size();
-
- Mesh *mesh = BKE_mesh_new_nomain(verts.size(), 0, 0, tot_loops, tot_polys);
-
- /* Write vertices. */
- for (const int i : verts.index_range()) {
- const blender::float3 co = blender::float3(verts[i].asV());
- copy_v3_v3(mesh->mvert[i].co, co);
- }
-
- /* Write triangles. */
- for (const int i : tris.index_range()) {
- mesh->mpoly[i].loopstart = 3 * i;
- mesh->mpoly[i].totloop = 3;
- for (int j = 0; j < 3; j++) {
- /* Reverse vertex order to get correct normals. */
- mesh->mloop[3 * i + j].v = tris[i][2 - j];
- }
- }
-
- /* Write quads. */
- const int poly_offset = tris.size();
- const int loop_offset = tris.size() * 3;
- for (const int i : quads.index_range()) {
- mesh->mpoly[poly_offset + i].loopstart = loop_offset + 4 * i;
- mesh->mpoly[poly_offset + i].totloop = 4;
- for (int j = 0; j < 4; j++) {
- /* Reverse vertex order to get correct normals. */
- mesh->mloop[loop_offset + 4 * i + j].v = quads[i][3 - j];
- }
- }
-
- BKE_mesh_calc_edges(mesh, false, false);
- BKE_mesh_calc_normals(mesh);
- return mesh;
-}
-#endif
-
static Mesh *create_empty_mesh(const Mesh *input_mesh)
{
Mesh *new_mesh = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
@@ -296,16 +164,35 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return create_empty_mesh(input_mesh);
}
- const openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
+ const openvdb::GridBase::ConstPtr local_grid = BKE_volume_grid_openvdb_for_read(volume,
+ 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);
+ /* `imat` had floating point issues and wasn't affine. */
+ imat.setCol(3, openvdb::Vec4d(0, 0, 0, 1));
+ transform->postMult(imat);
+
+ /* Create a temporary transformed grid. The underlying tree is shared. */
+ openvdb::GridBase::ConstPtr transformed_grid = local_grid->copyGridReplacingTransform(transform);
+
+ blender::bke::VolumeToMeshResolution resolution;
+ resolution.mode = (VolumeToMeshResolutionMode)vmmd->resolution_mode;
+ if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT) {
+ resolution.settings.voxel_amount = vmmd->voxel_amount;
+ }
+ if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
+ resolution.settings.voxel_size = vmmd->voxel_size;
+ }
- const VolumeGridType grid_type = BKE_volume_grid_type(volume_grid);
- VolumeToMeshOp to_mesh_op{*grid, *vmmd, *ctx};
- if (!BKE_volume_grid_type_operation(grid_type, to_mesh_op)) {
- BKE_modifier_set_error(ctx->object, md, "Expected a scalar grid");
+ Mesh *mesh = blender::bke::volume_to_mesh(
+ *transformed_grid, resolution, vmmd->threshold, vmmd->adaptivity);
+ if (mesh == nullptr) {
+ BKE_modifier_set_error(ctx->object, md, "Could not generate mesh from grid");
return create_empty_mesh(input_mesh);
}
- Mesh *mesh = new_mesh_from_openvdb_data(to_mesh_op.verts, to_mesh_op.tris, to_mesh_op.quads);
BKE_mesh_copy_settings(mesh, input_mesh);
if (vmmd->flag & VOLUME_TO_MESH_USE_SMOOTH_SHADE) {
BKE_mesh_smooth_flag_set(mesh, true);
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index ed4d658eb4f..64c240eb5fd 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -26,6 +26,7 @@ set(INC
intern
shader
texture
+ ../editors/include
../blenkernel
../blenlib
../blentranslation
@@ -142,15 +143,21 @@ set(SRC
geometry/nodes/node_geo_align_rotation_to_vector.cc
geometry/nodes/node_geo_attribute_color_ramp.cc
+ geometry/nodes/node_geo_attribute_combine_xyz.cc
geometry/nodes/node_geo_attribute_compare.cc
geometry/nodes/node_geo_attribute_fill.cc
geometry/nodes/node_geo_attribute_math.cc
geometry/nodes/node_geo_attribute_mix.cc
+ geometry/nodes/node_geo_attribute_sample_texture.cc
+ geometry/nodes/node_geo_attribute_proximity.cc
geometry/nodes/node_geo_attribute_randomize.cc
+ geometry/nodes/node_geo_attribute_separate_xyz.cc
geometry/nodes/node_geo_attribute_vector_math.cc
geometry/nodes/node_geo_boolean.cc
+ geometry/nodes/node_geo_collection_info.cc
geometry/nodes/node_geo_common.cc
geometry/nodes/node_geo_edge_split.cc
+ geometry/nodes/node_geo_is_viewport.cc
geometry/nodes/node_geo_join_geometry.cc
geometry/nodes/node_geo_object_info.cc
geometry/nodes/node_geo_point_distribute.cc
@@ -159,9 +166,11 @@ set(SRC
geometry/nodes/node_geo_point_scale.cc
geometry/nodes/node_geo_point_separate.cc
geometry/nodes/node_geo_point_translate.cc
+ geometry/nodes/node_geo_points_to_volume.cc
geometry/nodes/node_geo_subdivision_surface.cc
geometry/nodes/node_geo_transform.cc
geometry/nodes/node_geo_triangulate.cc
+ geometry/nodes/node_geo_volume_to_mesh.cc
geometry/node_geometry_exec.cc
geometry/node_geometry_tree.cc
geometry/node_geometry_util.cc
@@ -347,6 +356,10 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
+if(WITH_TBB)
+ add_definitions(-DWITH_TBB)
+endif()
+
if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
@@ -366,4 +379,11 @@ if(WITH_OPENSUBDIV)
add_definitions(-DWITH_OPENSUBDIV)
endif()
+if(WITH_OPENVDB)
+ list(APPEND INC_SYS
+ ${OPENVDB_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
+endif()
+
blender_add_lib(bf_nodes "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/nodes/NOD_derived_node_tree.hh b/source/blender/nodes/NOD_derived_node_tree.hh
index 4d594a77ebc..62affe43895 100644
--- a/source/blender/nodes/NOD_derived_node_tree.hh
+++ b/source/blender/nodes/NOD_derived_node_tree.hh
@@ -80,6 +80,7 @@ class DInputSocket : public DSocket {
private:
Vector<DOutputSocket *> linked_sockets_;
Vector<DGroupInput *> linked_group_inputs_;
+ bool is_multi_input_socket_;
friend DerivedNodeTree;
@@ -90,6 +91,7 @@ class DInputSocket : public DSocket {
Span<const DGroupInput *> linked_group_inputs() const;
bool is_linked() const;
+ bool is_multi_input_socket() const;
};
class DOutputSocket : public DSocket {
@@ -362,6 +364,11 @@ inline bool DInputSocket::is_linked() const
return linked_sockets_.size() > 0 || linked_group_inputs_.size() > 0;
}
+inline bool DInputSocket::is_multi_input_socket() const
+{
+ return is_multi_input_socket_;
+}
+
/* --------------------------------------------------------------------
* DOutputSocket inline methods.
*/
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
index 75dd8f89bc8..b5279f7d914 100644
--- a/source/blender/nodes/NOD_function.h
+++ b/source/blender/nodes/NOD_function.h
@@ -21,13 +21,13 @@ extern "C" {
#endif
void register_node_type_fn_boolean_math(void);
+void register_node_type_fn_combine_strings(void);
void register_node_type_fn_float_compare(void);
-void register_node_type_fn_switch(void);
void register_node_type_fn_group_instance_id(void);
-void register_node_type_fn_combine_strings(void);
+void register_node_type_fn_input_vector(void);
void register_node_type_fn_object_transforms(void);
void register_node_type_fn_random_float(void);
-void register_node_type_fn_input_vector(void);
+void register_node_type_fn_switch(void);
#ifdef __cplusplus
}
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 523d0cfa24d..8980855fd51 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -26,27 +26,35 @@ void register_node_tree_type_geo(void);
void register_node_type_geo_group(void);
+void register_node_type_geo_align_rotation_to_vector(void);
+void register_node_type_geo_attribute_color_ramp(void);
+void register_node_type_geo_attribute_combine_xyz(void);
+void register_node_type_geo_attribute_compare(void);
void register_node_type_geo_attribute_fill(void);
+void register_node_type_geo_attribute_math(void);
+void register_node_type_geo_attribute_mix(void);
+void register_node_type_geo_attribute_proximity(void);
+void register_node_type_geo_attribute_randomize(void);
+void register_node_type_geo_attribute_separate_xyz(void);
void register_node_type_geo_attribute_vector_math(void);
void register_node_type_geo_boolean(void);
+void register_node_type_geo_collection_info(void);
void register_node_type_geo_edge_split(void);
-void register_node_type_geo_transform(void);
-void register_node_type_geo_subdivision_surface(void);
-void register_node_type_geo_triangulate(void);
+void register_node_type_geo_is_viewport(void);
+void register_node_type_geo_join_geometry(void);
+void register_node_type_geo_object_info(void);
void register_node_type_geo_point_distribute(void);
void register_node_type_geo_point_instance(void);
-void register_node_type_geo_object_info(void);
-void register_node_type_geo_attribute_randomize(void);
-void register_node_type_geo_attribute_math(void);
-void register_node_type_geo_join_geometry(void);
-void register_node_type_geo_point_separate(void);
+void register_node_type_geo_point_rotate(void);
void register_node_type_geo_point_scale(void);
+void register_node_type_geo_point_separate(void);
void register_node_type_geo_point_translate(void);
-void register_node_type_geo_attribute_compare(void);
-void register_node_type_geo_attribute_mix(void);
-void register_node_type_geo_attribute_color_ramp(void);
-void register_node_type_geo_point_rotate(void);
-void register_node_type_geo_align_rotation_to_vector(void);
+void register_node_type_geo_points_to_volume(void);
+void register_node_type_geo_sample_texture(void);
+void register_node_type_geo_subdivision_surface(void);
+void register_node_type_geo_transform(void);
+void register_node_type_geo_triangulate(void);
+void register_node_type_geo_volume_to_mesh(void);
#ifdef __cplusplus
}
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index f278d6b4107..91d46e3951f 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -24,12 +24,16 @@
#include "DNA_node_types.h"
+struct Depsgraph;
+
namespace blender::nodes {
using bke::BooleanReadAttribute;
using bke::BooleanWriteAttribute;
using bke::Color4fReadAttribute;
using bke::Color4fWriteAttribute;
+using bke::Float2ReadAttribute;
+using bke::Float2WriteAttribute;
using bke::Float3ReadAttribute;
using bke::Float3WriteAttribute;
using bke::FloatReadAttribute;
@@ -54,18 +58,21 @@ class GeoNodeExecParams {
GValueMap<StringRef> &output_values_;
const PersistentDataHandleMap &handle_map_;
const Object *self_object_;
+ Depsgraph *depsgraph_;
public:
GeoNodeExecParams(const bNode &node,
GValueMap<StringRef> &input_values,
GValueMap<StringRef> &output_values,
const PersistentDataHandleMap &handle_map,
- const Object *self_object)
+ const Object *self_object,
+ Depsgraph *depsgraph)
: node_(node),
input_values_(input_values),
output_values_(output_values),
handle_map_(handle_map),
- self_object_(self_object)
+ self_object_(self_object),
+ depsgraph_(depsgraph)
{
}
@@ -97,6 +104,25 @@ class GeoNodeExecParams {
}
/**
+ * Get input as vector for multi input socket with the given identifier.
+ *
+ * This method can only be called once for each identifier.
+ */
+ template<typename T> Vector<T> extract_multi_input(StringRef identifier)
+ {
+ Vector<T> values;
+ values.append(input_values_.extract<T>(identifier));
+ int i = 1;
+ std::string sub_identifier = identifier + "[1]";
+ while (input_values_.contains(sub_identifier)) {
+ values.append(input_values_.extract<T>(sub_identifier));
+ i++;
+ sub_identifier = identifier + "[" + std::to_string(i) + "]";
+ }
+ return values;
+ }
+
+ /**
* Get the input value for the input socket with the given identifier.
*
* This makes a copy of the value, which is fine for most types but should be avoided for
@@ -163,6 +189,11 @@ class GeoNodeExecParams {
return self_object_;
}
+ Depsgraph *depsgraph() const
+ {
+ return depsgraph_;
+ }
+
/**
* Creates a read-only attribute based on node inputs. The method automatically detects which
* input with the given name is available.
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index e91b385a87e..15f078cebf2 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -289,6 +289,14 @@ DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_VECTOR_MATH, def_geo_attribute_vector_m
DefNode(GeometryNode, GEO_NODE_ALIGN_ROTATION_TO_VECTOR, def_geo_align_rotation_to_vector, "ALIGN_ROTATION_TO_VECTOR", AlignRotationToVector, "Align Rotation to Vector", "")
DefNode(GeometryNode, GEO_NODE_POINT_SCALE, def_geo_point_scale, "POINT_SCALE", PointScale, "Point Scale", "")
DefNode(GeometryNode, GEO_NODE_POINT_TRANSLATE, def_geo_point_translate, "POINT_TRANSLATE", PointTranslate, "Point Translate", "")
+DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE, def_geo_attribute_sample_texture, "ATTRIBUTE_SAMPLE_TEXTURE", AttributeSampleTexture, "Attribute Sample Texture", "")
+DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POINTS_TO_VOLUME", PointsToVolume, "Points to Volume", "")
+DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "")
+DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "")
+DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_PROXIMITY, def_geo_attribute_proximity, "ATTRIBUTE_PROXIMITY", AttributeProximity, "Attribute Proximity", "")
+DefNode(GeometryNode, GEO_NODE_VOLUME_TO_MESH, def_geo_volume_to_mesh, "VOLUME_TO_MESH", VolumeToMesh, "Volume to Mesh", "")
+DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_COMBINE_XYZ, def_geo_attribute_combine_xyz, "ATTRIBUTE_COMBINE_XYZ", AttributeCombineXYZ, "Attribute Combine XYZ", "")
+DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_SEPARATE_XYZ, def_geo_attribute_separate_xyz, "ATTRIBUTE_SEPARATE_XYZ", AttributeSeparateXYZ, "Attribute Separate XYZ", "")
/* undefine macros */
#undef DefNode
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 9148cef7805..7a83ff8e016 100644
--- a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
+++ b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
@@ -19,6 +19,9 @@
#include "RNA_enum_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "node_function_util.hh"
static bNodeSocketTemplate fn_node_boolean_math_in[] = {
@@ -32,6 +35,11 @@ static bNodeSocketTemplate fn_node_boolean_math_out[] = {
{-1, ""},
};
+static void fn_node_boolean_math_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+}
+
static void node_boolean_math_update(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sockB = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
@@ -86,5 +94,6 @@ void register_node_type_fn_boolean_math()
node_type_label(&ntype, node_boolean_math_label);
node_type_update(&ntype, node_boolean_math_update);
ntype.expand_in_mf_network = node_boolean_expand_in_mf_network;
+ ntype.draw_buttons = fn_node_boolean_math_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/function/nodes/node_fn_float_compare.cc b/source/blender/nodes/function/nodes/node_fn_float_compare.cc
index 93c79a48571..6c8df8f2ea0 100644
--- a/source/blender/nodes/function/nodes/node_fn_float_compare.cc
+++ b/source/blender/nodes/function/nodes/node_fn_float_compare.cc
@@ -21,6 +21,9 @@
#include "RNA_enum_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "node_function_util.hh"
static bNodeSocketTemplate fn_node_float_compare_in[] = {
@@ -35,6 +38,11 @@ static bNodeSocketTemplate fn_node_float_compare_out[] = {
{-1, ""},
};
+static void geo_node_float_compare_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+}
+
static void node_float_compare_update(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sockEpsilon = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
@@ -105,5 +113,6 @@ void register_node_type_fn_float_compare()
node_type_label(&ntype, node_float_compare_label);
node_type_update(&ntype, node_float_compare_update);
ntype.expand_in_mf_network = node_float_compare_expand_in_mf_network;
+ ntype.draw_buttons = geo_node_float_compare_layout;
nodeRegisterType(&ntype);
}
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 c2707f6307a..2cd4eb1d9df 100644
--- a/source/blender/nodes/function/nodes/node_fn_input_vector.cc
+++ b/source/blender/nodes/function/nodes/node_fn_input_vector.cc
@@ -18,11 +18,20 @@
#include "BLI_hash.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
static bNodeSocketTemplate fn_node_input_vector_out[] = {
{SOCK_VECTOR, N_("Vector")},
{-1, ""},
};
+static void fn_node_input_vector_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "vector", UI_ITEM_R_EXPAND, "", ICON_NONE);
+}
+
static void fn_node_vector_input_expand_in_mf_network(
blender::nodes::NodeMFNetworkBuilder &builder)
{
@@ -50,6 +59,6 @@ void register_node_type_fn_input_vector()
node_type_storage(
&ntype, "NodeInputVector", node_free_standard_storage, node_copy_standard_storage);
ntype.expand_in_mf_network = fn_node_vector_input_expand_in_mf_network;
-
+ ntype.draw_buttons = fn_node_input_vector_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/function/nodes/node_fn_switch.cc b/source/blender/nodes/function/nodes/node_fn_switch.cc
index 281ddb05c76..5187decbbe5 100644
--- a/source/blender/nodes/function/nodes/node_fn_switch.cc
+++ b/source/blender/nodes/function/nodes/node_fn_switch.cc
@@ -15,8 +15,17 @@
*/
#include "BLI_listbase.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "node_function_util.hh"
+static void fn_node_switch_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+}
+
static bNodeSocketTemplate fn_node_switch_in[] = {
{SOCK_BOOLEAN, N_("Switch")},
@@ -72,5 +81,6 @@ void register_node_type_fn_switch()
fn_node_type_base(&ntype, FN_NODE_SWITCH, "Switch", 0, 0);
node_type_socket_templates(&ntype, fn_node_switch_in, fn_node_switch_out);
node_type_update(&ntype, fn_node_switch_update);
+ ntype.draw_buttons = fn_node_switch_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 53af6073793..daaccf4450b 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -54,6 +54,8 @@ static int attribute_data_type_complexity(const CustomDataType data_type)
return 1;
case CD_PROP_FLOAT:
return 2;
+ case CD_PROP_FLOAT2:
+ return 3;
case CD_PROP_FLOAT3:
return 4;
case CD_PROP_COLOR:
diff --git a/source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc b/source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc
index eac77b25bd6..e592bd0bda8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc
@@ -18,6 +18,9 @@
#include "BLI_math_rotation.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
static bNodeSocketTemplate geo_node_align_rotation_to_vector_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_STRING, N_("Factor")},
@@ -32,32 +35,25 @@ static bNodeSocketTemplate geo_node_align_rotation_to_vector_out[] = {
{-1, ""},
};
-namespace blender::nodes {
-
-static void align_rotations_on_component(GeometryComponent &component,
- const GeoNodeExecParams &params)
+static void geo_node_align_rotation_to_vector_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
{
- const bNode &node = params.node();
- const NodeGeometryAlignRotationToVector &storage = *(const NodeGeometryAlignRotationToVector *)
- node.storage;
-
- OutputAttributePtr rotation_attribute = component.attribute_try_get_for_output(
- "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
- if (!rotation_attribute) {
- return;
- }
- MutableSpan<float3> rotations = rotation_attribute->get_span<float3>();
-
- FloatReadAttribute factors = params.get_input_attribute<float>(
- "Factor", component, ATTR_DOMAIN_POINT, 1.0f);
- Float3ReadAttribute vectors = params.get_input_attribute<float3>(
- "Vector", component, ATTR_DOMAIN_POINT, {0, 0, 1});
+ uiItemR(layout, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "pivot_axis", 0, IFACE_("Pivot"), ICON_NONE);
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "input_type_factor", 0, IFACE_("Factor"), ICON_NONE);
+ uiItemR(col, ptr, "input_type_vector", 0, IFACE_("Vector"), ICON_NONE);
+}
- float3 main_axis{0, 0, 0};
- main_axis[storage.axis] = 1;
+namespace blender::nodes {
- const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
- for (const int i : IndexRange(domain_size)) {
+static void align_rotations_auto_pivot(const Float3ReadAttribute &vectors,
+ const FloatReadAttribute &factors,
+ const float3 local_main_axis,
+ MutableSpan<float3> rotations)
+{
+ for (const int i : IndexRange(vectors.size())) {
const float3 vector = vectors[i];
if (is_zero_v3(vector)) {
continue;
@@ -66,7 +62,7 @@ static void align_rotations_on_component(GeometryComponent &component,
float old_rotation[3][3];
eul_to_mat3(old_rotation, rotations[i]);
float3 old_axis;
- mul_v3_m3v3(old_axis, old_rotation, main_axis);
+ mul_v3_m3v3(old_axis, old_rotation, local_main_axis);
const float3 new_axis = vector.normalized();
const float3 rotation_axis = float3::cross_high_precision(old_axis, new_axis);
@@ -84,6 +80,81 @@ static void align_rotations_on_component(GeometryComponent &component,
rotations[i] = new_rotation;
}
+}
+
+static void align_rotations_fixed_pivot(const Float3ReadAttribute &vectors,
+ const FloatReadAttribute &factors,
+ const float3 local_main_axis,
+ const float3 local_pivot_axis,
+ MutableSpan<float3> rotations)
+{
+ if (local_main_axis == local_pivot_axis) {
+ /* Can't compute any meaningful rotation angle in this case. */
+ return;
+ }
+
+ for (const int i : IndexRange(vectors.size())) {
+ const float3 vector = vectors[i];
+ if (is_zero_v3(vector)) {
+ continue;
+ }
+
+ float old_rotation[3][3];
+ eul_to_mat3(old_rotation, rotations[i]);
+ float3 old_axis;
+ mul_v3_m3v3(old_axis, old_rotation, local_main_axis);
+ float3 pivot_axis;
+ mul_v3_m3v3(pivot_axis, old_rotation, local_pivot_axis);
+
+ float full_angle = angle_signed_on_axis_v3v3_v3(vector, old_axis, pivot_axis);
+ if (full_angle > M_PI) {
+ /* Make sure the point is rotated as little as possible. */
+ full_angle -= 2.0f * M_PI;
+ }
+ const float angle = factors[i] * full_angle;
+
+ float rotation[3][3];
+ axis_angle_to_mat3(rotation, pivot_axis, angle);
+
+ float new_rotation_matrix[3][3];
+ mul_m3_m3m3(new_rotation_matrix, rotation, old_rotation);
+
+ float3 new_rotation;
+ mat3_to_eul(new_rotation, new_rotation_matrix);
+
+ rotations[i] = new_rotation;
+ }
+}
+
+static void align_rotations_on_component(GeometryComponent &component,
+ const GeoNodeExecParams &params)
+{
+ const bNode &node = params.node();
+ const NodeGeometryAlignRotationToVector &storage = *(const NodeGeometryAlignRotationToVector *)
+ node.storage;
+
+ OutputAttributePtr rotation_attribute = component.attribute_try_get_for_output(
+ "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+ if (!rotation_attribute) {
+ return;
+ }
+ MutableSpan<float3> rotations = rotation_attribute->get_span<float3>();
+
+ FloatReadAttribute factors = params.get_input_attribute<float>(
+ "Factor", component, ATTR_DOMAIN_POINT, 1.0f);
+ Float3ReadAttribute vectors = params.get_input_attribute<float3>(
+ "Vector", component, ATTR_DOMAIN_POINT, {0, 0, 1});
+
+ float3 local_main_axis{0, 0, 0};
+ local_main_axis[storage.axis] = 1;
+ if (storage.pivot_axis == GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_AUTO) {
+ align_rotations_auto_pivot(vectors, factors, local_main_axis, rotations);
+ }
+ else {
+ float3 local_pivot_axis{0, 0, 0};
+ local_pivot_axis[storage.pivot_axis - 1] = 1;
+ align_rotations_fixed_pivot(vectors, factors, local_main_axis, local_pivot_axis, rotations);
+ }
rotation_attribute.apply_span_and_save();
}
@@ -145,5 +216,6 @@ void register_node_type_geo_align_rotation_to_vector()
node_free_standard_storage,
node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_align_rotation_to_vector_exec;
+ ntype.draw_buttons = geo_node_align_rotation_to_vector_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
index 9b0900e19ab..179e418214c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
@@ -18,6 +18,9 @@
#include "BKE_colorband.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
static bNodeSocketTemplate geo_node_attribute_color_ramp_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_STRING, N_("Attribute")},
@@ -30,6 +33,13 @@ static bNodeSocketTemplate geo_node_attribute_color_ramp_out[] = {
{-1, ""},
};
+static void geo_node_attribute_color_ramp_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
+}
+
namespace blender::nodes {
static void execute_on_component(const GeoNodeExecParams &params, GeometryComponent &component)
@@ -104,5 +114,6 @@ void register_node_type_geo_attribute_color_ramp()
node_type_init(&ntype, blender::nodes::geo_node_attribute_color_ramp_init);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
ntype.geometry_node_execute = blender::nodes::geo_node_attribute_color_ramp_exec;
+ ntype.draw_buttons = geo_node_attribute_color_ramp_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc
new file mode 100644
index 00000000000..a231b4f9e92
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc
@@ -0,0 +1,135 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_geometry_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+static bNodeSocketTemplate geo_node_attribute_combine_xyz_in[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_STRING, N_("X")},
+ {SOCK_FLOAT, N_("X"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX},
+ {SOCK_STRING, N_("Y")},
+ {SOCK_FLOAT, N_("Y"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX},
+ {SOCK_STRING, N_("Z")},
+ {SOCK_FLOAT, N_("Z"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX},
+ {SOCK_STRING, N_("Result")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_attribute_combine_xyz_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+static void geo_node_attribute_combine_xyz_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "input_type_x", 0, IFACE_("Type X"), ICON_NONE);
+ uiItemR(layout, ptr, "input_type_y", 0, IFACE_("Type Y"), ICON_NONE);
+ uiItemR(layout, ptr, "input_type_z", 0, IFACE_("Type Z"), ICON_NONE);
+}
+
+namespace blender::nodes {
+
+static void geo_node_attribute_combine_xyz_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeAttributeCombineXYZ *data = (NodeAttributeCombineXYZ *)MEM_callocN(
+ sizeof(NodeAttributeCombineXYZ), __func__);
+
+ data->input_type_x = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
+ data->input_type_y = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
+ data->input_type_z = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
+ node->storage = data;
+}
+
+static void geo_node_attribute_combine_xyz_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeAttributeCombineXYZ *node_storage = (NodeAttributeCombineXYZ *)node->storage;
+ update_attribute_input_socket_availabilities(
+ *node, "X", (GeometryNodeAttributeInputMode)node_storage->input_type_x);
+ update_attribute_input_socket_availabilities(
+ *node, "Y", (GeometryNodeAttributeInputMode)node_storage->input_type_y);
+ update_attribute_input_socket_availabilities(
+ *node, "Z", (GeometryNodeAttributeInputMode)node_storage->input_type_z);
+}
+
+static void combine_attributes(GeometryComponent &component, const GeoNodeExecParams &params)
+{
+ const std::string result_name = params.get_input<std::string>("Result");
+ /* The result domain is always point for now. */
+ const AttributeDomain result_domain = ATTR_DOMAIN_POINT;
+ if (result_name.empty()) {
+ return;
+ }
+
+ OutputAttributePtr attribute_result = component.attribute_try_get_for_output(
+ result_name, result_domain, CD_PROP_FLOAT3);
+ if (!attribute_result) {
+ return;
+ }
+ FloatReadAttribute attribute_x = params.get_input_attribute<float>(
+ "X", component, result_domain, 0.0f);
+ FloatReadAttribute attribute_y = params.get_input_attribute<float>(
+ "Y", component, result_domain, 0.0f);
+ FloatReadAttribute attribute_z = params.get_input_attribute<float>(
+ "Z", component, result_domain, 0.0f);
+
+ MutableSpan<float3> results = attribute_result->get_span_for_write_only<float3>();
+ for (const int i : results.index_range()) {
+ const float x = attribute_x[i];
+ const float y = attribute_y[i];
+ const float z = attribute_z[i];
+ const float3 result = float3(x, y, z);
+ results[i] = result;
+ }
+ attribute_result.apply_span_and_save();
+}
+
+static void geo_node_attribute_combine_xyz_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+
+ if (geometry_set.has<MeshComponent>()) {
+ combine_attributes(geometry_set.get_component_for_write<MeshComponent>(), params);
+ }
+ if (geometry_set.has<PointCloudComponent>()) {
+ combine_attributes(geometry_set.get_component_for_write<PointCloudComponent>(), params);
+ }
+
+ params.set_output("Geometry", geometry_set);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_attribute_combine_xyz()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_ATTRIBUTE_COMBINE_XYZ, "Attribute Combine XYZ", NODE_CLASS_ATTRIBUTE, 0);
+ node_type_socket_templates(
+ &ntype, geo_node_attribute_combine_xyz_in, geo_node_attribute_combine_xyz_out);
+ node_type_init(&ntype, blender::nodes::geo_node_attribute_combine_xyz_init);
+ node_type_update(&ntype, blender::nodes::geo_node_attribute_combine_xyz_update);
+ node_type_storage(
+ &ntype, "NodeAttributeCombineXYZ", node_free_standard_storage, node_copy_standard_storage);
+ ntype.geometry_node_execute = blender::nodes::geo_node_attribute_combine_xyz_exec;
+ ntype.draw_buttons = geo_node_attribute_combine_xyz_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
index 20a2b2127c2..5e434a7f96d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
@@ -26,6 +26,9 @@
#include "DNA_mesh_types.h"
#include "DNA_pointcloud_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "NOD_math_functions.hh"
static bNodeSocketTemplate geo_node_attribute_compare_in[] = {
@@ -48,10 +51,19 @@ static bNodeSocketTemplate geo_node_attribute_compare_out[] = {
{-1, ""},
};
+static void geo_node_attribute_compare_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "input_type_a", 0, IFACE_("Type A"), ICON_NONE);
+ uiItemR(layout, ptr, "input_type_b", 0, IFACE_("Type B"), ICON_NONE);
+}
+
static void geo_node_attribute_compare_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeCompare *data = (NodeAttributeCompare *)MEM_callocN(sizeof(NodeAttributeCompare),
- "attribute mix node");
+ __func__);
data->operation = NODE_FLOAT_COMPARE_GREATER_THAN;
data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
@@ -327,6 +339,7 @@ void register_node_type_geo_attribute_compare()
node_type_socket_templates(
&ntype, geo_node_attribute_compare_in, geo_node_attribute_compare_out);
ntype.geometry_node_execute = blender::nodes::geo_node_attribute_compare_exec;
+ ntype.draw_buttons = geo_node_attribute_compare_layout;
node_type_update(&ntype, blender::nodes::geo_node_attribute_compare_update);
node_type_storage(
&ntype, "NodeAttributeCompare", node_free_standard_storage, node_copy_standard_storage);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
index 9cec4070f89..92b47769d1f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
@@ -21,6 +21,9 @@
#include "DNA_mesh_types.h"
#include "DNA_pointcloud_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
static bNodeSocketTemplate geo_node_attribute_fill_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_STRING, N_("Attribute")},
@@ -36,6 +39,12 @@ static bNodeSocketTemplate geo_node_attribute_fill_out[] = {
{-1, ""},
};
+static void geo_node_attribute_fill_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+ // uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
+}
+
static void geo_node_attribute_fill_init(bNodeTree *UNUSED(tree), bNode *node)
{
node->custom1 = CD_PROP_FLOAT;
@@ -131,5 +140,6 @@ void register_node_type_geo_attribute_fill()
node_type_init(&ntype, geo_node_attribute_fill_init);
node_type_update(&ntype, geo_node_attribute_fill_update);
ntype.geometry_node_execute = blender::nodes::geo_node_attribute_fill_exec;
+ ntype.draw_buttons = geo_node_attribute_fill_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc
index f8ec9124db3..076f7a9ee28 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc
@@ -26,6 +26,9 @@
#include "DNA_mesh_types.h"
#include "DNA_pointcloud_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "NOD_math_functions.hh"
static bNodeSocketTemplate geo_node_attribute_math_in[] = {
@@ -34,6 +37,8 @@ static bNodeSocketTemplate geo_node_attribute_math_in[] = {
{SOCK_FLOAT, N_("A"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
{SOCK_STRING, N_("B")},
{SOCK_FLOAT, N_("B"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
+ {SOCK_STRING, N_("C")},
+ {SOCK_FLOAT, N_("C"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
{SOCK_STRING, N_("Result")},
{-1, ""},
};
@@ -43,14 +48,91 @@ static bNodeSocketTemplate geo_node_attribute_math_out[] = {
{-1, ""},
};
+static bool operation_use_input_c(const NodeMathOperation operation)
+{
+ return ELEM(operation,
+ NODE_MATH_MULTIPLY_ADD,
+ NODE_MATH_SMOOTH_MIN,
+ NODE_MATH_SMOOTH_MAX,
+ NODE_MATH_WRAP,
+ NODE_MATH_COMPARE);
+}
+
+static bool operation_use_input_b(const NodeMathOperation operation)
+{
+ switch (operation) {
+ case NODE_MATH_ADD:
+ case NODE_MATH_SUBTRACT:
+ case NODE_MATH_MULTIPLY:
+ case NODE_MATH_DIVIDE:
+ case NODE_MATH_POWER:
+ case NODE_MATH_LOGARITHM:
+ case NODE_MATH_MINIMUM:
+ case NODE_MATH_MAXIMUM:
+ case NODE_MATH_LESS_THAN:
+ case NODE_MATH_GREATER_THAN:
+ case NODE_MATH_MODULO:
+ case NODE_MATH_ARCTAN2:
+ case NODE_MATH_SNAP:
+ case NODE_MATH_WRAP:
+ case NODE_MATH_COMPARE:
+ case NODE_MATH_MULTIPLY_ADD:
+ case NODE_MATH_PINGPONG:
+ case NODE_MATH_SMOOTH_MIN:
+ case NODE_MATH_SMOOTH_MAX:
+ return true;
+ case NODE_MATH_SINE:
+ case NODE_MATH_COSINE:
+ case NODE_MATH_TANGENT:
+ case NODE_MATH_ARCSINE:
+ case NODE_MATH_ARCCOSINE:
+ case NODE_MATH_ARCTANGENT:
+ case NODE_MATH_ROUND:
+ case NODE_MATH_ABSOLUTE:
+ case NODE_MATH_FLOOR:
+ case NODE_MATH_CEIL:
+ case NODE_MATH_FRACTION:
+ case NODE_MATH_SQRT:
+ case NODE_MATH_INV_SQRT:
+ case NODE_MATH_SIGN:
+ case NODE_MATH_EXPONENT:
+ case NODE_MATH_RADIANS:
+ case NODE_MATH_DEGREES:
+ case NODE_MATH_SINH:
+ case NODE_MATH_COSH:
+ case NODE_MATH_TANH:
+ case NODE_MATH_TRUNC:
+ return false;
+ }
+ BLI_assert(false);
+ return false;
+}
+
+static void geo_node_attribute_math_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeAttributeMath *node_storage = (NodeAttributeMath *)node->storage;
+ NodeMathOperation operation = (NodeMathOperation)node_storage->operation;
+
+ uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "input_type_a", 0, IFACE_("Type A"), ICON_NONE);
+
+ if (operation_use_input_b(operation)) {
+ uiItemR(layout, ptr, "input_type_b", 0, IFACE_("Type B"), ICON_NONE);
+ }
+ if (operation_use_input_c(operation)) {
+ uiItemR(layout, ptr, "input_type_c", 0, IFACE_("Type C"), ICON_NONE);
+ }
+}
+
static void geo_node_attribute_math_init(bNodeTree *UNUSED(tree), bNode *node)
{
- NodeAttributeMath *data = (NodeAttributeMath *)MEM_callocN(sizeof(NodeAttributeMath),
- "NodeAttributeMath");
+ NodeAttributeMath *data = (NodeAttributeMath *)MEM_callocN(sizeof(NodeAttributeMath), __func__);
data->operation = NODE_MATH_ADD;
data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
+ data->input_type_c = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
node->storage = data;
}
@@ -58,38 +140,64 @@ namespace blender::nodes {
static void geo_node_attribute_math_update(bNodeTree *UNUSED(ntree), bNode *node)
{
- NodeAttributeMath *node_storage = (NodeAttributeMath *)node->storage;
+ NodeAttributeMath &node_storage = *(NodeAttributeMath *)node->storage;
+ NodeMathOperation operation = static_cast<NodeMathOperation>(node_storage.operation);
update_attribute_input_socket_availabilities(
- *node, "A", (GeometryNodeAttributeInputMode)node_storage->input_type_a);
+ *node, "A", (GeometryNodeAttributeInputMode)node_storage.input_type_a);
update_attribute_input_socket_availabilities(
- *node, "B", (GeometryNodeAttributeInputMode)node_storage->input_type_b);
+ *node,
+ "B",
+ (GeometryNodeAttributeInputMode)node_storage.input_type_b,
+ operation_use_input_b(operation));
+ update_attribute_input_socket_availabilities(
+ *node,
+ "C",
+ (GeometryNodeAttributeInputMode)node_storage.input_type_c,
+ operation_use_input_c(operation));
}
-static void do_math_operation(const FloatReadAttribute &input_a,
- const FloatReadAttribute &input_b,
- FloatWriteAttribute result,
- const int operation)
+static void do_math_operation(Span<float> span_a,
+ Span<float> span_b,
+ Span<float> span_c,
+ MutableSpan<float> span_result,
+ const NodeMathOperation operation)
{
- const int size = input_a.size();
-
- Span<float> span_a = input_a.get_span();
- Span<float> span_b = input_b.get_span();
- MutableSpan<float> span_result = result.get_span_for_write_only();
+ bool success = try_dispatch_float_math_fl_fl_fl_to_fl(
+ operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
+ for (const int i : IndexRange(span_result.size())) {
+ span_result[i] = math_function(span_a[i], span_b[i], span_c[i]);
+ }
+ });
+ BLI_assert(success);
+ UNUSED_VARS_NDEBUG(success);
+}
+static void do_math_operation(Span<float> span_a,
+ Span<float> span_b,
+ MutableSpan<float> span_result,
+ const NodeMathOperation operation)
+{
bool success = try_dispatch_float_math_fl_fl_to_fl(
operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- for (const int i : IndexRange(size)) {
- const float in1 = span_a[i];
- const float in2 = span_b[i];
- const float out = math_function(in1, in2);
- span_result[i] = out;
+ for (const int i : IndexRange(span_result.size())) {
+ span_result[i] = math_function(span_a[i], span_b[i]);
}
});
+ BLI_assert(success);
+ UNUSED_VARS_NDEBUG(success);
+}
- result.apply_span();
-
- /* The operation is not supported by this node currently. */
+static void do_math_operation(Span<float> span_input,
+ MutableSpan<float> span_result,
+ const NodeMathOperation operation)
+{
+ bool success = try_dispatch_float_math_fl_to_fl(
+ operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
+ for (const int i : IndexRange(span_result.size())) {
+ span_result[i] = math_function(span_input[i]);
+ }
+ });
BLI_assert(success);
UNUSED_VARS_NDEBUG(success);
}
@@ -98,7 +206,7 @@ static void attribute_math_calc(GeometryComponent &component, const GeoNodeExecP
{
const bNode &node = params.node();
const NodeAttributeMath *node_storage = (const NodeAttributeMath *)node.storage;
- const int operation = node_storage->operation;
+ const NodeMathOperation operation = static_cast<NodeMathOperation>(node_storage->operation);
/* The result type of this node is always float. */
const CustomDataType result_type = CD_PROP_FLOAT;
@@ -115,15 +223,44 @@ static void attribute_math_calc(GeometryComponent &component, const GeoNodeExecP
ReadAttributePtr attribute_a = params.get_input_attribute(
"A", component, result_domain, result_type, nullptr);
- ReadAttributePtr attribute_b = params.get_input_attribute(
- "B", component, result_domain, result_type, nullptr);
- if (!attribute_a || !attribute_b) {
- /* Attribute wasn't found. */
+ if (!attribute_a) {
return;
}
- do_math_operation(*attribute_a, *attribute_b, *attribute_result, operation);
- attribute_result.save();
+ /* Note that passing the data with `get_span<float>()` works
+ * because the attributes were accessed with #CD_PROP_FLOAT. */
+ if (operation_use_input_b(operation)) {
+ ReadAttributePtr attribute_b = params.get_input_attribute(
+ "B", component, result_domain, result_type, nullptr);
+ if (!attribute_b) {
+ return;
+ }
+ if (operation_use_input_c(operation)) {
+ ReadAttributePtr attribute_c = params.get_input_attribute(
+ "C", component, result_domain, result_type, nullptr);
+ if (!attribute_c) {
+ return;
+ }
+ do_math_operation(attribute_a->get_span<float>(),
+ attribute_b->get_span<float>(),
+ attribute_c->get_span<float>(),
+ attribute_result->get_span_for_write_only<float>(),
+ operation);
+ }
+ else {
+ do_math_operation(attribute_a->get_span<float>(),
+ attribute_b->get_span<float>(),
+ attribute_result->get_span_for_write_only<float>(),
+ operation);
+ }
+ }
+ else {
+ do_math_operation(attribute_a->get_span<float>(),
+ attribute_result->get_span_for_write_only<float>(),
+ operation);
+ }
+
+ attribute_result.apply_span_and_save();
}
static void geo_node_attribute_math_exec(GeoNodeExecParams params)
@@ -149,9 +286,10 @@ void register_node_type_geo_attribute_math()
geo_node_type_base(&ntype, GEO_NODE_ATTRIBUTE_MATH, "Attribute Math", NODE_CLASS_ATTRIBUTE, 0);
node_type_socket_templates(&ntype, geo_node_attribute_math_in, geo_node_attribute_math_out);
ntype.geometry_node_execute = blender::nodes::geo_node_attribute_math_exec;
+ ntype.draw_buttons = geo_node_attribute_math_layout;
node_type_update(&ntype, blender::nodes::geo_node_attribute_math_update);
node_type_init(&ntype, geo_node_attribute_math_init);
node_type_storage(
- &ntype, "NodeAttributeCompare", node_free_standard_storage, node_copy_standard_storage);
+ &ntype, "NodeAttributeMath", node_free_standard_storage, node_copy_standard_storage);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
index 58d67145e75..976970d06b1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
@@ -18,6 +18,9 @@
#include "DNA_material_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "node_geometry_util.hh"
static bNodeSocketTemplate geo_node_attribute_mix_in[] = {
@@ -41,6 +44,15 @@ static bNodeSocketTemplate geo_node_mix_attribute_out[] = {
{-1, ""},
};
+static void geo_node_attribute_mix_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "blend_type", 0, "", ICON_NONE);
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "input_type_factor", 0, IFACE_("Factor"), ICON_NONE);
+ uiItemR(col, ptr, "input_type_a", 0, IFACE_("A"), ICON_NONE);
+ uiItemR(col, ptr, "input_type_b", 0, IFACE_("B"), ICON_NONE);
+}
+
namespace blender::nodes {
static void do_mix_operation_float(const int blend_mode,
@@ -204,6 +216,7 @@ void register_node_type_geo_attribute_mix()
node_type_socket_templates(&ntype, geo_node_attribute_mix_in, geo_node_mix_attribute_out);
node_type_init(&ntype, blender::nodes::geo_node_attribute_mix_init);
node_type_update(&ntype, blender::nodes::geo_node_attribute_mix_update);
+ ntype.draw_buttons = geo_node_attribute_mix_layout;
node_type_storage(
&ntype, "NodeAttributeMix", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_attribute_mix_exec;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_proximity.cc
new file mode 100644
index 00000000000..45f20ca553a
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_proximity.cc
@@ -0,0 +1,235 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_kdopbvh.h"
+#include "BLI_kdtree.h"
+#include "BLI_task.hh"
+#include "BLI_timeit.hh"
+
+#include "DNA_mesh_types.h"
+
+#include "BKE_bvhutils.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+static bNodeSocketTemplate geo_node_attribute_proximity_in[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_GEOMETRY, N_("Target")},
+ {SOCK_STRING, N_("Result")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_attribute_proximity_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+static void geo_node_attribute_proximity_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "target_geometry_element", 0, "", ICON_NONE);
+}
+
+static void geo_attribute_proximity_init(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeGeometryAttributeProximity *node_storage = (NodeGeometryAttributeProximity *)MEM_callocN(
+ sizeof(NodeGeometryAttributeProximity), __func__);
+
+ node_storage->target_geometry_element =
+ GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_FACES;
+ node->storage = node_storage;
+}
+
+namespace blender::nodes {
+
+static void proximity_calc(MutableSpan<float> distance_span,
+ Span<float3> positions,
+ BVHTreeFromMesh &tree_data_mesh,
+ BVHTreeFromPointCloud &tree_data_pointcloud,
+ const bool bvh_mesh_success,
+ const bool bvh_pointcloud_success)
+{
+ /* The pointcloud loop uses the values already in the span,
+ * which is only set if the mesh BVH is used (because it's first). */
+ if (!bvh_mesh_success) {
+ distance_span.fill(FLT_MAX);
+ }
+
+ IndexRange range = positions.index_range();
+ parallel_for(range, 512, [&](IndexRange range) {
+ BVHTreeNearest nearest;
+
+ if (bvh_mesh_success) {
+ copy_v3_fl(nearest.co, FLT_MAX);
+ nearest.index = -1;
+
+ for (int i : range) {
+ nearest.dist_sq = len_squared_v3v3(nearest.co, positions[i]);
+ BLI_bvhtree_find_nearest(tree_data_mesh.tree,
+ positions[i],
+ &nearest,
+ tree_data_mesh.nearest_callback,
+ &tree_data_mesh);
+ distance_span[i] = sqrtf(nearest.dist_sq);
+ }
+ }
+
+ if (bvh_pointcloud_success) {
+ copy_v3_fl(nearest.co, FLT_MAX);
+ nearest.index = -1;
+
+ for (int i : range) {
+ /* Use the distance to the last found point as upper bound to speedup the bvh lookup. */
+ nearest.dist_sq = len_squared_v3v3(nearest.co, positions[i]);
+ BLI_bvhtree_find_nearest(tree_data_pointcloud.tree,
+ positions[i],
+ &nearest,
+ tree_data_pointcloud.nearest_callback,
+ &tree_data_pointcloud);
+ distance_span[i] = std::min(distance_span[i], sqrtf(nearest.dist_sq));
+ }
+ }
+ });
+}
+
+static bool bvh_from_mesh(const Mesh *target_mesh,
+ int target_geometry_element,
+ BVHTreeFromMesh &r_tree_data_mesh)
+{
+ BVHCacheType bvh_type = BVHTREE_FROM_LOOPTRI;
+ switch (target_geometry_element) {
+ case GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_POINTS:
+ bvh_type = BVHTREE_FROM_VERTS;
+ break;
+ case GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_EDGES:
+ bvh_type = BVHTREE_FROM_EDGES;
+ break;
+ case GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_FACES:
+ bvh_type = BVHTREE_FROM_LOOPTRI;
+ break;
+ }
+
+ /* This only updates a cache and can be considered to be logically const. */
+ BKE_bvhtree_from_mesh_get(&r_tree_data_mesh, const_cast<Mesh *>(target_mesh), bvh_type, 2);
+ if (r_tree_data_mesh.tree == nullptr) {
+ return false;
+ }
+ return true;
+}
+
+static bool bvh_from_pointcloud(const PointCloud *target_pointcloud,
+ BVHTreeFromPointCloud &r_tree_data_pointcloud)
+{
+ BKE_bvhtree_from_pointcloud_get(&r_tree_data_pointcloud, target_pointcloud, 2);
+ if (r_tree_data_pointcloud.tree == nullptr) {
+ return false;
+ }
+ return true;
+}
+
+static void attribute_calc_proximity(GeometryComponent &component,
+ GeometrySet &geometry_set_target,
+ GeoNodeExecParams &params)
+{
+ const std::string result_attribute_name = params.get_input<std::string>("Result");
+ OutputAttributePtr distance_attribute = component.attribute_try_get_for_output(
+ result_attribute_name, ATTR_DOMAIN_POINT, CD_PROP_FLOAT);
+
+ ReadAttributePtr position_attribute = component.attribute_try_get_for_read("position");
+ BLI_assert(position_attribute->custom_data_type() == CD_PROP_FLOAT3);
+
+ if (!distance_attribute || !position_attribute) {
+ return;
+ }
+
+ const bNode &node = params.node();
+ const NodeGeometryAttributeProximity &storage = *(const NodeGeometryAttributeProximity *)
+ node.storage;
+
+ BVHTreeFromMesh tree_data_mesh;
+ BVHTreeFromPointCloud tree_data_pointcloud;
+ bool bvh_mesh_success = false;
+ bool bvh_pointcloud_success = false;
+
+ if (geometry_set_target.has_mesh()) {
+ bvh_mesh_success = bvh_from_mesh(
+ geometry_set_target.get_mesh_for_read(), storage.target_geometry_element, tree_data_mesh);
+ }
+
+ if (geometry_set_target.has_pointcloud() &&
+ storage.target_geometry_element ==
+ GEO_NODE_ATTRIBUTE_PROXIMITY_TARGET_GEOMETRY_ELEMENT_POINTS) {
+ bvh_pointcloud_success = bvh_from_pointcloud(geometry_set_target.get_pointcloud_for_read(),
+ tree_data_pointcloud);
+ }
+
+ proximity_calc(distance_attribute->get_span_for_write_only<float>(),
+ position_attribute->get_span<float3>(),
+ tree_data_mesh,
+ tree_data_pointcloud,
+ bvh_mesh_success,
+ bvh_pointcloud_success);
+
+ if (bvh_mesh_success) {
+ free_bvhtree_from_mesh(&tree_data_mesh);
+ }
+ if (bvh_pointcloud_success) {
+ free_bvhtree_from_pointcloud(&tree_data_pointcloud);
+ }
+
+ distance_attribute.apply_span_and_save();
+}
+
+static void geo_node_attribute_proximity_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ GeometrySet geometry_set_target = params.extract_input<GeometrySet>("Target");
+
+ if (geometry_set.has<MeshComponent>()) {
+ attribute_calc_proximity(
+ geometry_set.get_component_for_write<MeshComponent>(), geometry_set_target, params);
+ }
+ if (geometry_set.has<PointCloudComponent>()) {
+ attribute_calc_proximity(
+ geometry_set.get_component_for_write<PointCloudComponent>(), geometry_set_target, params);
+ }
+
+ params.set_output("Geometry", geometry_set);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_attribute_proximity()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_ATTRIBUTE_PROXIMITY, "Attribute Proximity", NODE_CLASS_ATTRIBUTE, 0);
+ node_type_socket_templates(
+ &ntype, geo_node_attribute_proximity_in, geo_node_attribute_proximity_out);
+ node_type_init(&ntype, geo_attribute_proximity_init);
+ node_type_storage(&ntype,
+ "NodeGeometryAttributeProximity",
+ node_free_standard_storage,
+ node_copy_standard_storage);
+ ntype.geometry_node_execute = blender::nodes::geo_node_attribute_proximity_exec;
+ ntype.draw_buttons = geo_node_attribute_proximity_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
index 0e7bb25e659..f5765af83b3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
@@ -19,6 +19,9 @@
#include "BLI_hash.h"
#include "BLI_rand.hh"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "DNA_mesh_types.h"
#include "DNA_pointcloud_types.h"
@@ -38,6 +41,13 @@ static bNodeSocketTemplate geo_node_attribute_randomize_out[] = {
{-1, ""},
};
+static void geo_node_attribute_random_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+}
+
static void geo_node_attribute_randomize_init(bNodeTree *UNUSED(tree), bNode *node)
{
node->custom1 = CD_PROP_FLOAT;
@@ -50,8 +60,7 @@ static void geo_node_attribute_randomize_update(bNodeTree *UNUSED(ntree), bNode
bNodeSocket *sock_min_float = sock_max_vector->next;
bNodeSocket *sock_max_float = sock_min_float->next;
- const int data_type = node->custom1;
-
+ const CustomDataType data_type = static_cast<CustomDataType>(node->custom1);
nodeSetSocketAvailability(sock_min_vector, data_type == CD_PROP_FLOAT3);
nodeSetSocketAvailability(sock_max_vector, data_type == CD_PROP_FLOAT3);
nodeSetSocketAvailability(sock_min_float, data_type == CD_PROP_FLOAT);
@@ -86,8 +95,11 @@ static void randomize_attribute_bool(BooleanWriteAttribute attribute,
attribute.apply_span();
}
-static void randomize_attribute_float(
- FloatWriteAttribute attribute, float min, float max, Span<uint32_t> hashes, const int seed)
+static void randomize_attribute_float(FloatWriteAttribute attribute,
+ const float min,
+ const float max,
+ Span<uint32_t> hashes,
+ const int seed)
{
MutableSpan<float> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@@ -97,8 +109,11 @@ static void randomize_attribute_float(
attribute.apply_span();
}
-static void randomize_attribute_float3(
- Float3WriteAttribute attribute, float3 min, float3 max, Span<uint32_t> hashes, const int seed)
+static void randomize_attribute_float3(Float3WriteAttribute attribute,
+ const float3 min,
+ const float3 max,
+ Span<uint32_t> hashes,
+ const int seed)
{
MutableSpan<float3> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@@ -129,8 +144,7 @@ Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &compo
}
else {
/* If there is no "id" attribute for per-point variation, just create it here. */
- RandomNumberGenerator rng;
- rng.seed(0);
+ RandomNumberGenerator rng(0);
for (const int i : hashes.index_range()) {
hashes[i] = rng.get_uint32();
}
@@ -211,5 +225,6 @@ void register_node_type_geo_attribute_randomize()
node_type_init(&ntype, geo_node_attribute_randomize_init);
node_type_update(&ntype, geo_node_attribute_randomize_update);
ntype.geometry_node_execute = blender::nodes::geo_node_random_attribute_exec;
+ ntype.draw_buttons = geo_node_attribute_random_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
new file mode 100644
index 00000000000..b6a960e5617
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
@@ -0,0 +1,118 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_compiler_attrs.h"
+
+#include "DNA_texture_types.h"
+
+#include "BKE_texture.h"
+
+#include "RE_texture.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+static bNodeSocketTemplate geo_node_attribute_sample_texture_in[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_STRING, N_("Mapping")},
+ {SOCK_STRING, N_("Result")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_attribute_sample_texture_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+static void geo_node_attribute_sample_texture_layout(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr)
+{
+ uiTemplateID(layout, C, ptr, "texture", "texture.new", NULL, NULL, 0, ICON_NONE, NULL);
+}
+
+namespace blender::nodes {
+
+static void execute_on_component(GeometryComponent &component, const GeoNodeExecParams &params)
+{
+ const bNode &node = params.node();
+ Tex *texture = reinterpret_cast<Tex *>(node.id);
+ const std::string result_attribute_name = params.get_input<std::string>("Result");
+
+ if (texture == nullptr) {
+ return;
+ }
+
+ const std::string mapping_name = params.get_input<std::string>("Mapping");
+ if (!component.attribute_exists(mapping_name)) {
+ return;
+ }
+
+ OutputAttributePtr attribute_out = component.attribute_try_get_for_output(
+ result_attribute_name, ATTR_DOMAIN_POINT, CD_PROP_COLOR);
+ if (!attribute_out) {
+ return;
+ }
+
+ Float3ReadAttribute mapping_attribute = component.attribute_get_for_read<float3>(
+ mapping_name, ATTR_DOMAIN_POINT, {0, 0, 0});
+
+ MutableSpan<Color4f> colors = attribute_out->get_span<Color4f>();
+ for (const int i : IndexRange(mapping_attribute.size())) {
+ TexResult texture_result = {0};
+ const float3 position = mapping_attribute[i];
+ /* For legacy reasons we have to map [0, 1] to [-1, 1] to support uv mappings. */
+ const float3 remapped_position = position * 2.0f - float3(1.0f);
+ BKE_texture_get_value(nullptr, texture, remapped_position, &texture_result, false);
+ colors[i] = {texture_result.tr, texture_result.tg, texture_result.tb, texture_result.ta};
+ }
+ attribute_out.apply_span_and_save();
+}
+
+static void geo_node_attribute_sample_texture_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+
+ if (geometry_set.has<MeshComponent>()) {
+ execute_on_component(geometry_set.get_component_for_write<MeshComponent>(), params);
+ }
+ if (geometry_set.has<PointCloudComponent>()) {
+ execute_on_component(geometry_set.get_component_for_write<PointCloudComponent>(), params);
+ }
+
+ params.set_output("Geometry", geometry_set);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_sample_texture()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype,
+ GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE,
+ "Attribute Sample Texture",
+ NODE_CLASS_ATTRIBUTE,
+ 0);
+ node_type_size_preset(&ntype, NODE_SIZE_LARGE);
+ node_type_socket_templates(
+ &ntype, geo_node_attribute_sample_texture_in, geo_node_attribute_sample_texture_out);
+ ntype.geometry_node_execute = blender::nodes::geo_node_attribute_sample_texture_exec;
+ ntype.draw_buttons = geo_node_attribute_sample_texture_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc
new file mode 100644
index 00000000000..07941f7db79
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc
@@ -0,0 +1,148 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "DNA_material_types.h"
+
+#include "node_geometry_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+static bNodeSocketTemplate geo_node_attribute_separate_xyz_in[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_STRING, N_("Vector")},
+ {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
+ {SOCK_STRING, N_("Result X")},
+ {SOCK_STRING, N_("Result Y")},
+ {SOCK_STRING, N_("Result Z")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_attribute_separate_xyz_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+static void geo_node_attribute_separate_xyz_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "input_type", 0, IFACE_("Type"), ICON_NONE);
+}
+
+namespace blender::nodes {
+
+static void geo_node_attribute_separate_xyz_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeAttributeSeparateXYZ *data = (NodeAttributeSeparateXYZ *)MEM_callocN(
+ sizeof(NodeAttributeSeparateXYZ), __func__);
+ data->input_type = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
+ node->storage = data;
+}
+
+static void geo_node_attribute_separate_xyz_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeAttributeSeparateXYZ *node_storage = (NodeAttributeSeparateXYZ *)node->storage;
+ update_attribute_input_socket_availabilities(
+ *node, "Vector", (GeometryNodeAttributeInputMode)node_storage->input_type);
+}
+
+static void extract_input(const int index, const Span<float3> &input, MutableSpan<float> result)
+{
+ for (const int i : result.index_range()) {
+ /* Get the component of the float3. (0: X, 1: Y, 2: Z). */
+ const float component = input[i][index];
+ result[i] = component;
+ }
+}
+
+static void separate_attribute(GeometryComponent &component, const GeoNodeExecParams &params)
+{
+ const std::string result_name_x = params.get_input<std::string>("Result X");
+ const std::string result_name_y = params.get_input<std::string>("Result Y");
+ const std::string result_name_z = params.get_input<std::string>("Result Z");
+ /* The node is only for float3 to float conversions. */
+ const CustomDataType input_type = CD_PROP_FLOAT3;
+ const CustomDataType result_type = CD_PROP_FLOAT;
+ /* The result domain is always point for now. */
+ const AttributeDomain result_domain = ATTR_DOMAIN_POINT;
+
+ /* No output to write to. */
+ if (result_name_x.empty() && result_name_y.empty() && result_name_z.empty()) {
+ return;
+ }
+
+ ReadAttributePtr attribute_input = params.get_input_attribute(
+ "Vector", component, result_domain, input_type, nullptr);
+ if (!attribute_input) {
+ return;
+ }
+ const Span<float3> input_span = attribute_input->get_span<float3>();
+
+ OutputAttributePtr attribute_result_x = component.attribute_try_get_for_output(
+ result_name_x, result_domain, result_type);
+ OutputAttributePtr attribute_result_y = component.attribute_try_get_for_output(
+ result_name_y, result_domain, result_type);
+ OutputAttributePtr attribute_result_z = component.attribute_try_get_for_output(
+ result_name_z, result_domain, result_type);
+
+ /* Only extract the components for the outputs with a given attribute. */
+ if (attribute_result_x) {
+ extract_input(0, input_span, attribute_result_x->get_span_for_write_only<float>());
+ attribute_result_x.apply_span_and_save();
+ }
+ if (attribute_result_y) {
+ extract_input(1, input_span, attribute_result_y->get_span_for_write_only<float>());
+ attribute_result_y.apply_span_and_save();
+ }
+ if (attribute_result_z) {
+ extract_input(2, input_span, attribute_result_z->get_span_for_write_only<float>());
+ attribute_result_z.apply_span_and_save();
+ }
+}
+
+static void geo_node_attribute_separate_xyz_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+
+ if (geometry_set.has<MeshComponent>()) {
+ separate_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
+ }
+ if (geometry_set.has<PointCloudComponent>()) {
+ separate_attribute(geometry_set.get_component_for_write<PointCloudComponent>(), params);
+ }
+
+ params.set_output("Geometry", geometry_set);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_attribute_separate_xyz()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_ATTRIBUTE_SEPARATE_XYZ, "Attribute Separate XYZ", NODE_CLASS_ATTRIBUTE, 0);
+ node_type_socket_templates(
+ &ntype, geo_node_attribute_separate_xyz_in, geo_node_attribute_separate_xyz_out);
+ node_type_init(&ntype, blender::nodes::geo_node_attribute_separate_xyz_init);
+ node_type_update(&ntype, blender::nodes::geo_node_attribute_separate_xyz_update);
+ node_type_storage(
+ &ntype, "NodeAttributeSeparateXYZ", node_free_standard_storage, node_copy_standard_storage);
+ ntype.geometry_node_execute = blender::nodes::geo_node_attribute_separate_xyz_exec;
+ ntype.draw_buttons = geo_node_attribute_separate_xyz_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc
index 529906a35e7..62a291e8506 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc
@@ -26,6 +26,9 @@
#include "DNA_mesh_types.h"
#include "DNA_pointcloud_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "NOD_math_functions.hh"
static bNodeSocketTemplate geo_node_attribute_vector_math_in[] = {
@@ -46,25 +49,6 @@ static bNodeSocketTemplate geo_node_attribute_vector_math_out[] = {
{-1, ""},
};
-static void geo_node_attribute_vector_math_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeVectorMath *data = (NodeAttributeVectorMath *)MEM_callocN(
- sizeof(NodeAttributeVectorMath), __func__);
-
- data->operation = NODE_VECTOR_MATH_ADD;
- data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- node->storage = data;
-}
-
-static CustomDataType operation_get_read_type_b(const NodeVectorMathOperation operation)
-{
- if (operation == NODE_VECTOR_MATH_SCALE) {
- return CD_PROP_FLOAT;
- }
- return CD_PROP_FLOAT3;
-}
-
static bool operation_use_input_b(const NodeVectorMathOperation operation)
{
return !ELEM(operation,
@@ -84,6 +68,44 @@ static bool operation_use_input_c(const NodeVectorMathOperation operation)
return operation == NODE_VECTOR_MATH_WRAP;
}
+static void geo_node_attribute_vector_math_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+ const NodeAttributeVectorMath &node_storage = *(NodeAttributeVectorMath *)node->storage;
+ const NodeVectorMathOperation operation = (const NodeVectorMathOperation)node_storage.operation;
+
+ uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "input_type_a", 0, IFACE_("Type A"), ICON_NONE);
+
+ if (operation_use_input_b(operation)) {
+ uiItemR(layout, ptr, "input_type_b", 0, IFACE_("Type B"), ICON_NONE);
+ }
+ if (operation_use_input_c(operation)) {
+ uiItemR(layout, ptr, "input_type_c", 0, IFACE_("Type C"), ICON_NONE);
+ }
+}
+
+static CustomDataType operation_get_read_type_b(const NodeVectorMathOperation operation)
+{
+ if (operation == NODE_VECTOR_MATH_SCALE) {
+ return CD_PROP_FLOAT;
+ }
+ return CD_PROP_FLOAT3;
+}
+
+static void geo_node_attribute_vector_math_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeAttributeVectorMath *data = (NodeAttributeVectorMath *)MEM_callocN(
+ sizeof(NodeAttributeVectorMath), __func__);
+
+ data->operation = NODE_VECTOR_MATH_ADD;
+ data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
+ data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
+ node->storage = data;
+}
+
static CustomDataType operation_get_result_type(const NodeVectorMathOperation operation)
{
switch (operation) {
@@ -419,6 +441,7 @@ void register_node_type_geo_attribute_vector_math()
node_type_socket_templates(
&ntype, geo_node_attribute_vector_math_in, geo_node_attribute_vector_math_out);
ntype.geometry_node_execute = blender::nodes::geo_node_attribute_vector_math_exec;
+ ntype.draw_buttons = geo_node_attribute_vector_math_layout;
node_type_update(&ntype, blender::nodes::geo_node_attribute_vector_math_update);
node_type_init(&ntype, geo_node_attribute_vector_math_init);
node_type_storage(
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index 19178546e40..403b74b2fef 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -24,6 +24,9 @@
#include "RNA_enum_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "BKE_mesh.h"
#include "bmesh.h"
@@ -42,6 +45,11 @@ static bNodeSocketTemplate geo_node_boolean_out[] = {
{-1, ""},
};
+static void geo_node_boolean_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+}
+
static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
{
return BM_elem_flag_test(f, BM_ELEM_DRAW) ? 1 : 0;
@@ -147,6 +155,7 @@ void register_node_type_geo_boolean()
geo_node_type_base(&ntype, GEO_NODE_BOOLEAN, "Boolean", NODE_CLASS_GEOMETRY, 0);
node_type_socket_templates(&ntype, geo_node_boolean_in, geo_node_boolean_out);
+ ntype.draw_buttons = geo_node_boolean_layout;
ntype.geometry_node_execute = blender::nodes::geo_node_boolean_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
new file mode 100644
index 00000000000..42ad434ffcd
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
@@ -0,0 +1,108 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_geometry_util.hh"
+
+#include "BLI_math_matrix.h"
+
+#include "DNA_collection_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+static bNodeSocketTemplate geo_node_collection_info_in[] = {
+ {SOCK_COLLECTION, N_("Collection")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_collection_info_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+static void geo_node_collection_info_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "transform_space", 0, NULL, ICON_NONE);
+}
+
+namespace blender::nodes {
+
+static void geo_node_collection_info_exec(GeoNodeExecParams params)
+{
+ bke::PersistentCollectionHandle collection_handle =
+ params.extract_input<bke::PersistentCollectionHandle>("Collection");
+ Collection *collection = params.handle_map().lookup(collection_handle);
+
+ GeometrySet geometry_set_out;
+
+ if (collection == nullptr) {
+ params.set_output("Geometry", geometry_set_out);
+ return;
+ }
+
+ const bNode &bnode = params.node();
+ NodeGeometryCollectionInfo *node_storage = (NodeGeometryCollectionInfo *)bnode.storage;
+ const bool transform_space_relative = (node_storage->transform_space ==
+ GEO_NODE_TRANSFORM_SPACE_RELATIVE);
+
+ InstancedData instance;
+ instance.type = INSTANCE_DATA_TYPE_COLLECTION;
+ instance.data.collection = collection;
+
+ InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
+
+ float transform_mat[4][4];
+ unit_m4(transform_mat);
+ const Object *self_object = params.self_object();
+
+ if (transform_space_relative) {
+ copy_v3_v3(transform_mat[3], collection->instance_offset);
+
+ mul_m4_m4_pre(transform_mat, self_object->imat);
+
+ float3 self_loc;
+ copy_v3_v3(self_loc, self_object->obmat[3]);
+ }
+ instances.add_instance(instance, transform_mat, -1);
+
+ params.set_output("Geometry", geometry_set_out);
+}
+
+static void geo_node_collection_info_node_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeGeometryCollectionInfo *data = (NodeGeometryCollectionInfo *)MEM_callocN(
+ sizeof(NodeGeometryCollectionInfo), __func__);
+ data->transform_space = GEO_NODE_TRANSFORM_SPACE_ORIGINAL;
+ node->storage = data;
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_collection_info()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_COLLECTION_INFO, "Collection Info", NODE_CLASS_INPUT, 0);
+ node_type_socket_templates(&ntype, geo_node_collection_info_in, geo_node_collection_info_out);
+ node_type_init(&ntype, blender::nodes::geo_node_collection_info_node_init);
+ node_type_storage(&ntype,
+ "NodeGeometryCollectionInfo",
+ node_free_standard_storage,
+ node_copy_standard_storage);
+ ntype.geometry_node_execute = blender::nodes::geo_node_collection_info_exec;
+ ntype.draw_buttons = geo_node_collection_info_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc b/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc
new file mode 100644
index 00000000000..667beaa1722
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_geometry_util.hh"
+
+#include "DEG_depsgraph_query.h"
+
+static bNodeSocketTemplate geo_node_is_viewport_out[] = {
+ {SOCK_BOOLEAN, N_("Is Viewport")},
+ {-1, ""},
+};
+
+namespace blender::nodes {
+
+static void geo_node_is_viewport_exec(GeoNodeExecParams params)
+{
+ const Depsgraph *depsgraph = params.depsgraph();
+ const eEvaluationMode mode = DEG_get_mode(depsgraph);
+ const bool is_viewport = mode == DAG_EVAL_VIEWPORT;
+
+ params.set_output("Is Viewport", is_viewport);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_is_viewport()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_IS_VIEWPORT, "Is Viewport", NODE_CLASS_INPUT, 0);
+ node_type_socket_templates(&ntype, nullptr, geo_node_is_viewport_out);
+ ntype.geometry_node_execute = blender::nodes::geo_node_is_viewport_exec;
+ nodeRegisterType(&ntype);
+}
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 42402e23fa5..a56939a43c7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -24,8 +24,16 @@
#include "node_geometry_util.hh"
static bNodeSocketTemplate geo_node_join_geometry_in[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_GEOMETRY,
+ N_("Geometry"),
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ -1.0f,
+ 1.0f,
+ PROP_NONE,
+ SOCK_MULTI_INPUT},
{-1, ""},
};
@@ -138,17 +146,17 @@ static void determine_final_data_type_and_domain(Span<const GeometryComponent *>
CustomDataType *r_type,
AttributeDomain *r_domain)
{
+ Vector<CustomDataType> data_types;
for (const GeometryComponent *component : components) {
ReadAttributePtr attribute = component->attribute_try_get_for_read(attribute_name);
if (attribute) {
- /* TODO: Use data type with most information. */
- *r_type = bke::cpp_type_to_custom_data_type(attribute->cpp_type());
+ data_types.append(attribute->custom_data_type());
/* TODO: Use highest priority domain. */
*r_domain = attribute->domain();
- return;
}
}
- BLI_assert(false);
+
+ *r_type = attribute_data_type_highest_complexity(data_types);
}
static void fill_new_attribute(Span<const GeometryComponent *> src_components,
@@ -243,12 +251,20 @@ static void join_components(Span<const InstancesComponent *> src_components, Geo
}
}
+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>
-static void join_component_type(Span<const GeometrySet *> src_geometry_sets, GeometrySet &result)
+static void join_component_type(Span<GeometrySet> src_geometry_sets, GeometrySet &result)
{
Vector<const Component *> components;
- for (const GeometrySet *geometry_set : src_geometry_sets) {
- const Component *component = geometry_set->get_component_for_read<Component>();
+ for (const GeometrySet &geometry_set : src_geometry_sets) {
+ const Component *component = geometry_set.get_component_for_read<Component>();
if (component != nullptr && !component->is_empty()) {
components.append(component);
}
@@ -266,15 +282,13 @@ static void join_component_type(Span<const GeometrySet *> src_geometry_sets, Geo
static void geo_node_join_geometry_exec(GeoNodeExecParams params)
{
- GeometrySet geometry_set_a = params.extract_input<GeometrySet>("Geometry");
- GeometrySet geometry_set_b = params.extract_input<GeometrySet>("Geometry_001");
- GeometrySet geometry_set_result;
+ Vector<GeometrySet> geometry_sets = params.extract_multi_input<GeometrySet>("Geometry");
- std::array<const GeometrySet *, 2> src_geometry_sets = {&geometry_set_a, &geometry_set_b};
-
- join_component_type<MeshComponent>(src_geometry_sets, geometry_set_result);
- join_component_type<PointCloudComponent>(src_geometry_sets, geometry_set_result);
- join_component_type<InstancesComponent>(src_geometry_sets, geometry_set_result);
+ GeometrySet geometry_set_result;
+ join_component_type<MeshComponent>(geometry_sets, geometry_set_result);
+ join_component_type<PointCloudComponent>(geometry_sets, geometry_set_result);
+ join_component_type<InstancesComponent>(geometry_sets, geometry_set_result);
+ join_component_type<VolumeComponent>(geometry_sets, geometry_set_result);
params.set_output("Geometry", std::move(geometry_set_result));
}
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 ab5e4f8964a..4e26977b85a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
@@ -19,9 +19,13 @@
#include "BKE_mesh.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
+#include "BKE_volume.h"
#include "BLI_math_matrix.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
static bNodeSocketTemplate geo_node_object_info_in[] = {
{SOCK_OBJECT, N_("Object")},
{-1, ""},
@@ -35,6 +39,11 @@ static bNodeSocketTemplate geo_node_object_info_out[] = {
{-1, ""},
};
+static void geo_node_object_info_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "transform_space", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+}
+
namespace blender::nodes {
static void geo_node_object_info_exec(GeoNodeExecParams params)
{
@@ -86,6 +95,18 @@ static void geo_node_object_info_exec(GeoNodeExecParams params)
mesh_component.copy_vertex_group_names_from_object(*object);
}
}
+ if (object->type == OB_VOLUME) {
+ InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
+
+ if (transform_space_relative) {
+ instances.add_instance(object, transform);
+ }
+ else {
+ float unit_transform[4][4];
+ unit_m4(unit_transform);
+ instances.add_instance(object, unit_transform);
+ }
+ }
}
}
@@ -115,5 +136,6 @@ void register_node_type_geo_object_info()
node_type_storage(
&ntype, "NodeGeometryObjectInfo", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_object_info_exec;
+ ntype.draw_buttons = geo_node_object_info_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
index 2f1aa276532..93abed7926e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -26,12 +26,16 @@
#include "DNA_meshdata_types.h"
#include "DNA_pointcloud_types.h"
+#include "BKE_attribute_math.hh"
#include "BKE_bvhutils.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_pointcloud.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "node_geometry_util.hh"
static bNodeSocketTemplate geo_node_point_distribute_in[] = {
@@ -48,6 +52,13 @@ static bNodeSocketTemplate geo_node_point_distribute_out[] = {
{-1, ""},
};
+static void geo_node_point_distribute_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "distribute_method", 0, "", ICON_NONE);
+}
+
static void node_point_distribute_update(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sock_min_dist = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
@@ -217,13 +228,141 @@ BLI_NOINLINE static void eliminate_points_based_on_mask(Span<bool> elimination_m
}
}
-BLI_NOINLINE static void compute_remaining_point_data(const Mesh &mesh,
- Span<float3> bary_coords,
- Span<int> looptri_indices,
- MutableSpan<float3> r_normals,
- MutableSpan<int> r_ids,
- MutableSpan<float3> r_rotations)
+template<typename T>
+BLI_NOINLINE static void interpolate_attribute_point(const Mesh &mesh,
+ const Span<float3> bary_coords,
+ const Span<int> looptri_indices,
+ const Span<T> data_in,
+ MutableSpan<T> data_out)
+{
+ BLI_assert(data_in.size() == mesh.totvert);
+ Span<MLoopTri> looptris = get_mesh_looptris(mesh);
+
+ for (const int i : bary_coords.index_range()) {
+ const int looptri_index = looptri_indices[i];
+ const MLoopTri &looptri = looptris[looptri_index];
+ const float3 &bary_coord = bary_coords[i];
+
+ const int v0_index = mesh.mloop[looptri.tri[0]].v;
+ const int v1_index = mesh.mloop[looptri.tri[1]].v;
+ const int v2_index = mesh.mloop[looptri.tri[2]].v;
+
+ const T &v0 = data_in[v0_index];
+ const T &v1 = data_in[v1_index];
+ const T &v2 = data_in[v2_index];
+
+ const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
+ data_out[i] = interpolated_value;
+ }
+}
+
+template<typename T>
+BLI_NOINLINE static void interpolate_attribute_corner(const Mesh &mesh,
+ const Span<float3> bary_coords,
+ const Span<int> looptri_indices,
+ const Span<T> data_in,
+ MutableSpan<T> data_out)
+{
+ BLI_assert(data_in.size() == mesh.totloop);
+ Span<MLoopTri> looptris = get_mesh_looptris(mesh);
+
+ for (const int i : bary_coords.index_range()) {
+ const int looptri_index = looptri_indices[i];
+ const MLoopTri &looptri = looptris[looptri_index];
+ const float3 &bary_coord = bary_coords[i];
+
+ const int loop_index_0 = looptri.tri[0];
+ const int loop_index_1 = looptri.tri[1];
+ const int loop_index_2 = looptri.tri[2];
+
+ const T &v0 = data_in[loop_index_0];
+ const T &v1 = data_in[loop_index_1];
+ const T &v2 = data_in[loop_index_2];
+
+ const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
+ data_out[i] = interpolated_value;
+ }
+}
+
+BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices,
+ const StringRef attribute_name,
+ const ReadAttribute &attribute_in,
+ GeometryComponent &component)
+{
+ const CustomDataType data_type = attribute_in.custom_data_type();
+ const AttributeDomain domain = attribute_in.domain();
+ if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
+ /* Not supported currently. */
+ return;
+ }
+
+ OutputAttributePtr attribute_out = component.attribute_try_get_for_output(
+ attribute_name, ATTR_DOMAIN_POINT, data_type);
+ if (!attribute_out) {
+ return;
+ }
+
+ attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+
+ Span data_in = attribute_in.get_span<T>();
+ MutableSpan data_out = attribute_out->get_span_for_write_only<T>();
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT: {
+ interpolate_attribute_point<T>(mesh, bary_coords, looptri_indices, data_in, data_out);
+ break;
+ }
+ case ATTR_DOMAIN_CORNER: {
+ interpolate_attribute_corner<T>(mesh, bary_coords, looptri_indices, data_in, data_out);
+ break;
+ }
+ default: {
+ BLI_assert(false);
+ break;
+ }
+ }
+ });
+ attribute_out.apply_span_and_save();
+}
+
+BLI_NOINLINE static void interpolate_existing_attributes(const MeshComponent &mesh_component,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
+{
+ const Mesh &mesh = *mesh_component.get_for_read();
+
+ Set<std::string> attribute_names = mesh_component.attribute_names();
+ for (StringRefNull attribute_name : attribute_names) {
+ if (ELEM(attribute_name, "position", "normal", "id")) {
+ continue;
+ }
+
+ ReadAttributePtr attribute_in = mesh_component.attribute_try_get_for_read(attribute_name);
+ interpolate_attribute(
+ mesh, bary_coords, looptri_indices, attribute_name, *attribute_in, component);
+ }
+}
+
+BLI_NOINLINE static void compute_special_attributes(const Mesh &mesh,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
{
+ OutputAttributePtr id_attribute = component.attribute_try_get_for_output(
+ "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
+ OutputAttributePtr normal_attribute = component.attribute_try_get_for_output(
+ "normal", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+ OutputAttributePtr rotation_attribute = component.attribute_try_get_for_output(
+ "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+
+ MutableSpan<int> ids = id_attribute->get_span_for_write_only<int>();
+ MutableSpan<float3> normals = normal_attribute->get_span_for_write_only<float3>();
+ MutableSpan<float3> rotations = rotation_attribute->get_span_for_write_only<float3>();
+
Span<MLoopTri> looptris = get_mesh_looptris(mesh);
for (const int i : bary_coords.index_range()) {
const int looptri_index = looptri_indices[i];
@@ -237,10 +376,24 @@ BLI_NOINLINE static void compute_remaining_point_data(const Mesh &mesh,
const float3 v1_pos = mesh.mvert[v1_index].co;
const float3 v2_pos = mesh.mvert[v2_index].co;
- r_ids[i] = (int)(bary_coord.hash()) + looptri_index;
- normal_tri_v3(r_normals[i], v0_pos, v1_pos, v2_pos);
- r_rotations[i] = normal_to_euler_rotation(r_normals[i]);
+ ids[i] = (int)(bary_coord.hash()) + looptri_index;
+ normal_tri_v3(normals[i], v0_pos, v1_pos, v2_pos);
+ rotations[i] = normal_to_euler_rotation(normals[i]);
}
+
+ id_attribute.apply_span_and_save();
+ normal_attribute.apply_span_and_save();
+ rotation_attribute.apply_span_and_save();
+}
+
+BLI_NOINLINE static void add_remaining_point_attributes(const MeshComponent &mesh_component,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
+{
+ interpolate_existing_attributes(mesh_component, component, bary_coords, looptri_indices);
+ compute_special_attributes(
+ *mesh_component.get_for_read(), component, bary_coords, looptri_indices);
}
static void sample_mesh_surface_with_minimum_distance(const Mesh &mesh,
@@ -315,11 +468,6 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
break;
}
const int tot_points = positions.size();
- Array<float3> normals(tot_points);
- Array<int> stable_ids(tot_points);
- Array<float3> rotations(tot_points);
- compute_remaining_point_data(
- *mesh_in, bary_coords, looptri_indices, normals, stable_ids, rotations);
PointCloud *pointcloud = BKE_pointcloud_new_nomain(tot_points);
memcpy(pointcloud->co, positions.data(), sizeof(float3) * tot_points);
@@ -332,29 +480,7 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
geometry_set_out.get_component_for_write<PointCloudComponent>();
point_component.replace(pointcloud);
- {
- OutputAttributePtr stable_id_attribute = point_component.attribute_try_get_for_output(
- "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
- MutableSpan<int> stable_ids_span = stable_id_attribute->get_span<int>();
- stable_ids_span.copy_from(stable_ids);
- stable_id_attribute.apply_span_and_save();
- }
-
- {
- OutputAttributePtr normals_attribute = point_component.attribute_try_get_for_output(
- "normal", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
- MutableSpan<float3> normals_span = normals_attribute->get_span<float3>();
- normals_span.copy_from(normals);
- normals_attribute.apply_span_and_save();
- }
-
- {
- OutputAttributePtr rotations_attribute = point_component.attribute_try_get_for_output(
- "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
- MutableSpan<float3> rotations_span = rotations_attribute->get_span<float3>();
- rotations_span.copy_from(rotations);
- rotations_attribute.apply_span_and_save();
- }
+ add_remaining_point_attributes(mesh_component, point_component, bary_coords, looptri_indices);
params.set_output("Geometry", std::move(geometry_set_out));
}
@@ -369,5 +495,6 @@ void register_node_type_geo_point_distribute()
node_type_socket_templates(&ntype, geo_node_point_distribute_in, geo_node_point_distribute_out);
node_type_update(&ntype, node_point_distribute_update);
ntype.geometry_node_execute = blender::nodes::geo_node_point_distribute_exec;
+ ntype.draw_buttons = geo_node_point_distribute_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
index a96dc710427..1e7cf21f921 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
@@ -24,6 +24,9 @@
#include "BLI_hash.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "node_geometry_util.hh"
static bNodeSocketTemplate geo_node_point_instance_in[] = {
@@ -39,6 +42,14 @@ static bNodeSocketTemplate geo_node_point_instance_out[] = {
{-1, ""},
};
+static void geo_node_point_instance_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "instance_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ if (RNA_enum_get(ptr, "instance_type") == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION) {
+ uiItemR(layout, ptr, "use_whole_collection", 0, NULL, ICON_NONE);
+ }
+}
+
namespace blender::nodes {
static void geo_node_point_instance_update(bNodeTree *UNUSED(tree), bNode *node)
@@ -47,8 +58,10 @@ static void geo_node_point_instance_update(bNodeTree *UNUSED(tree), bNode *node)
bNodeSocket *collection_socket = object_socket->next;
bNodeSocket *seed_socket = collection_socket->next;
- GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)node->custom1;
- const bool use_whole_collection = node->custom2 == 0;
+ NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node->storage;
+ GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)node_storage->instance_type;
+ const bool use_whole_collection = (node_storage->flag &
+ GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION) != 0;
nodeSetSocketAvailability(object_socket, type == GEO_NODE_POINT_INSTANCE_TYPE_OBJECT);
nodeSetSocketAvailability(collection_socket, type == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION);
@@ -79,6 +92,8 @@ static void get_instanced_data__collection(
MutableSpan<std::optional<InstancedData>> r_instances_data)
{
const bNode &node = params.node();
+ NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node.storage;
+
bke::PersistentCollectionHandle collection_handle =
params.get_input<bke::PersistentCollectionHandle>("Collection");
Collection *collection = params.handle_map().lookup(collection_handle);
@@ -86,7 +101,8 @@ static void get_instanced_data__collection(
return;
}
- const bool use_whole_collection = node.custom2 == 0;
+ const bool use_whole_collection = (node_storage->flag &
+ GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION) != 0;
if (use_whole_collection) {
InstancedData instance;
instance.type = INSTANCE_DATA_TYPE_COLLECTION;
@@ -128,8 +144,9 @@ static Array<std::optional<InstancedData>> get_instanced_data(const GeoNodeExecP
const int amount)
{
const bNode &node = params.node();
- const GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)node.custom1;
-
+ NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node.storage;
+ const GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)
+ node_storage->instance_type;
Array<std::optional<InstancedData>> instances_data(amount);
switch (type) {
@@ -189,6 +206,16 @@ static void geo_node_point_instance_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set_out));
}
+
+static void geo_node_point_instance_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeGeometryPointInstance *data = (NodeGeometryPointInstance *)MEM_callocN(
+ sizeof(NodeGeometryPointInstance), __func__);
+ data->instance_type = GEO_NODE_POINT_INSTANCE_TYPE_OBJECT;
+ data->flag |= GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION;
+ node->storage = data;
+}
+
} // namespace blender::nodes
void register_node_type_geo_point_instance()
@@ -197,6 +224,10 @@ void register_node_type_geo_point_instance()
geo_node_type_base(&ntype, GEO_NODE_POINT_INSTANCE, "Point Instance", NODE_CLASS_GEOMETRY, 0);
node_type_socket_templates(&ntype, geo_node_point_instance_in, geo_node_point_instance_out);
+ node_type_init(&ntype, blender::nodes::geo_node_point_instance_init);
+ node_type_storage(
+ &ntype, "NodeGeometryPointInstance", node_free_standard_storage, node_copy_standard_storage);
+ ntype.draw_buttons = geo_node_point_instance_layout;
node_type_update(&ntype, blender::nodes::geo_node_point_instance_update);
ntype.geometry_node_execute = blender::nodes::geo_node_point_instance_exec;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_rotate.cc b/source/blender/nodes/geometry/nodes/node_geo_point_rotate.cc
index b1451dfb89e..3ca898bfd83 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_rotate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_rotate.cc
@@ -18,6 +18,9 @@
#include "BLI_math_rotation.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
static bNodeSocketTemplate geo_node_point_rotate_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_STRING, N_("Axis")},
@@ -34,6 +37,23 @@ static bNodeSocketTemplate geo_node_point_rotate_out[] = {
{-1, ""},
};
+static void geo_node_point_rotate_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ NodeGeometryRotatePoints *storage = (NodeGeometryRotatePoints *)((bNode *)ptr->data)->storage;
+
+ uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "space", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ uiLayout *col = uiLayoutColumn(layout, false);
+ if (storage->type == GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE) {
+ uiItemR(col, ptr, "input_type_axis", 0, IFACE_("Axis"), ICON_NONE);
+ uiItemR(col, ptr, "input_type_angle", 0, IFACE_("Angle"), ICON_NONE);
+ }
+ else {
+ uiItemR(col, ptr, "input_type_rotation", 0, IFACE_("Rotation"), ICON_NONE);
+ }
+}
+
namespace blender::nodes {
static void point_rotate__axis_angle__object_space(const int domain_size,
@@ -202,5 +222,6 @@ void register_node_type_geo_point_rotate()
node_type_storage(
&ntype, "NodeGeometryRotatePoints", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_point_rotate_exec;
+ ntype.draw_buttons = geo_node_point_rotate_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_scale.cc b/source/blender/nodes/geometry/nodes/node_geo_point_scale.cc
index 47fca93d2ab..78e23b783db 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_scale.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_scale.cc
@@ -18,6 +18,9 @@
#include "BKE_colorband.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
static bNodeSocketTemplate geo_node_point_scale_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_STRING, N_("Factor")},
@@ -30,6 +33,11 @@ static bNodeSocketTemplate geo_node_point_scale_out[] = {
{-1, ""},
};
+static void geo_node_point_scale_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "input_type", 0, IFACE_("Type"), ICON_NONE);
+}
+
namespace blender::nodes {
static void execute_on_component(GeoNodeExecParams params, GeometryComponent &component)
@@ -96,5 +104,6 @@ void register_node_type_geo_point_scale()
node_type_storage(
&ntype, "NodeGeometryPointScale", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_point_scale_exec;
+ ntype.draw_buttons = geo_node_point_scale_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_translate.cc b/source/blender/nodes/geometry/nodes/node_geo_point_translate.cc
index 72176b11fdb..f7f369f5d66 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_translate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_translate.cc
@@ -18,6 +18,9 @@
#include "BKE_colorband.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
static bNodeSocketTemplate geo_node_point_translate_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_STRING, N_("Translation")},
@@ -30,6 +33,11 @@ static bNodeSocketTemplate geo_node_point_translate_out[] = {
{-1, ""},
};
+static void geo_node_point_translate_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "input_type", 0, IFACE_("Type"), ICON_NONE);
+}
+
namespace blender::nodes {
static void execute_on_component(GeoNodeExecParams params, GeometryComponent &component)
@@ -97,5 +105,6 @@ void register_node_type_geo_point_translate()
node_free_standard_storage,
node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_point_translate_exec;
+ ntype.draw_buttons = geo_node_point_translate_layout;
nodeRegisterType(&ntype);
}
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
new file mode 100644
index 00000000000..428f129fb36
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
@@ -0,0 +1,273 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+# include <openvdb/tools/LevelSetUtil.h>
+# include <openvdb/tools/ParticlesToLevelSet.h>
+#endif
+
+#include "node_geometry_util.hh"
+
+#include "BKE_lib_id.h"
+#include "BKE_volume.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+static bNodeSocketTemplate geo_node_points_to_volume_in[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_FLOAT, N_("Density"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_FLOAT, N_("Voxel Size"), 0.3f, 0.0f, 0.0f, 0.0f, 0.01f, FLT_MAX},
+ {SOCK_FLOAT, N_("Voxel Amount"), 64.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_STRING, N_("Radius")},
+ {SOCK_FLOAT, N_("Radius"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_point_translate_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+static void geo_node_points_to_volume_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+ uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
+ uiItemR(layout, ptr, "input_type_radius", 0, IFACE_("Radius"), ICON_NONE);
+}
+
+namespace blender::nodes {
+
+#ifdef WITH_OPENVDB
+namespace {
+/* Implements the interface required by #openvdb::tools::ParticlesToLevelSet. */
+struct ParticleList {
+ using PosType = openvdb::Vec3R;
+
+ Span<float3> positions;
+ Span<float> radii;
+
+ size_t size() const
+ {
+ return (size_t)positions.size();
+ }
+
+ void getPos(size_t n, openvdb::Vec3R &xyz) const
+ {
+ xyz = &positions[n].x;
+ }
+
+ void getPosRad(size_t n, openvdb::Vec3R &xyz, openvdb::Real &radius) const
+ {
+ xyz = &positions[n].x;
+ radius = radii[n];
+ }
+};
+} // namespace
+
+static openvdb::FloatGrid::Ptr generate_volume_from_points(const Span<float3> positions,
+ const Span<float> radii,
+ const float density)
+{
+ /* Create a new grid that will be filled. #ParticlesToLevelSet requires the background value to
+ * be positive. It will be set to zero later on. */
+ openvdb::FloatGrid::Ptr new_grid = openvdb::FloatGrid::create(1.0f);
+
+ /* Create a narrow-band level set grid based on the positions and radii. */
+ openvdb::tools::ParticlesToLevelSet op{*new_grid};
+ /* Don't ignore particles based on their radius. */
+ op.setRmin(0.0f);
+ op.setRmax(FLT_MAX);
+ ParticleList particles{positions, radii};
+ op.rasterizeSpheres(particles);
+ op.finalize();
+
+ /* Convert the level set to a fog volume. This also sets the background value to zero. Inside the
+ * fog there will be a density of 1. */
+ openvdb::tools::sdfToFogVolume(*new_grid);
+
+ /* Take the desired density into account. */
+ openvdb::tools::foreach (new_grid->beginValueOn(),
+ [&](const openvdb::FloatGrid::ValueOnIter &iter) {
+ iter.modifyValue([&](float &value) { value *= density; });
+ });
+ return new_grid;
+}
+
+static float compute_voxel_size(const GeoNodeExecParams &params,
+ Span<float3> positions,
+ const float radius)
+{
+ const NodeGeometryPointsToVolume &storage =
+ *(const NodeGeometryPointsToVolume *)params.node().storage;
+
+ if (storage.resolution_mode == GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE) {
+ return params.get_input<float>("Voxel Size");
+ }
+
+ if (positions.is_empty()) {
+ return 0.0f;
+ }
+
+ float3 min, max;
+ INIT_MINMAX(min, max);
+ minmax_v3v3_v3_array(min, max, (float(*)[3])positions.data(), positions.size());
+
+ const float voxel_amount = params.get_input<float>("Voxel Amount");
+ if (voxel_amount <= 1) {
+ return 0.0f;
+ }
+
+ /* The voxel size adapts to the final size of the volume. */
+ const float diagonal = float3::distance(min, max);
+ const float extended_diagonal = diagonal + 2.0f * radius;
+ const float voxel_size = extended_diagonal / voxel_amount;
+ return voxel_size;
+}
+
+static void gather_point_data_from_component(const GeoNodeExecParams &params,
+ const GeometryComponent &component,
+ Vector<float3> &r_positions,
+ Vector<float> &r_radii)
+{
+ Float3ReadAttribute positions = component.attribute_get_for_read<float3>(
+ "position", ATTR_DOMAIN_POINT, {0, 0, 0});
+ FloatReadAttribute radii = params.get_input_attribute<float>(
+ "Radius", component, ATTR_DOMAIN_POINT, 0.0f);
+
+ r_positions.extend(positions.get_span());
+ r_radii.extend(radii.get_span());
+}
+
+static void convert_to_grid_index_space(const float voxel_size,
+ MutableSpan<float3> positions,
+ MutableSpan<float> radii)
+{
+ const float voxel_size_inv = 1.0f / voxel_size;
+ for (const int i : positions.index_range()) {
+ positions[i] *= voxel_size_inv;
+ /* Better align generated grid with source points. */
+ positions[i] -= float3(0.5f);
+ radii[i] *= voxel_size_inv;
+ }
+}
+
+static void initialize_volume_component_from_points(const GeometrySet &geometry_set_in,
+ GeometrySet &geometry_set_out,
+ const GeoNodeExecParams &params)
+{
+ Vector<float3> positions;
+ Vector<float> radii;
+
+ if (geometry_set_in.has<MeshComponent>()) {
+ gather_point_data_from_component(
+ params, *geometry_set_in.get_component_for_read<MeshComponent>(), positions, radii);
+ }
+ if (geometry_set_in.has<PointCloudComponent>()) {
+ gather_point_data_from_component(
+ params, *geometry_set_in.get_component_for_read<PointCloudComponent>(), positions, radii);
+ }
+
+ const float max_radius = *std::max_element(radii.begin(), radii.end());
+ const float voxel_size = compute_voxel_size(params, positions, max_radius);
+ if (voxel_size == 0.0f || positions.is_empty()) {
+ return;
+ }
+
+ Volume *volume = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
+ BKE_volume_init_grids(volume);
+
+ VolumeGrid *c_density_grid = BKE_volume_grid_add(volume, "density", VOLUME_GRID_FLOAT);
+ openvdb::FloatGrid::Ptr density_grid = openvdb::gridPtrCast<openvdb::FloatGrid>(
+ BKE_volume_grid_openvdb_for_write(volume, c_density_grid, false));
+
+ const float density = params.get_input<float>("Density");
+ convert_to_grid_index_space(voxel_size, positions, radii);
+ openvdb::FloatGrid::Ptr new_grid = generate_volume_from_points(positions, radii, density);
+ /* This merge is cheap, because the #density_grid is empty. */
+ density_grid->merge(*new_grid);
+ density_grid->transform().postScale(voxel_size);
+
+ VolumeComponent &volume_component = geometry_set_out.get_component_for_write<VolumeComponent>();
+ volume_component.replace(volume);
+}
+#endif
+
+static void geo_node_points_to_volume_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set_in = params.extract_input<GeometrySet>("Geometry");
+ GeometrySet geometry_set_out;
+
+#ifdef WITH_OPENVDB
+ initialize_volume_component_from_points(geometry_set_in, geometry_set_out, params);
+#endif
+
+ params.set_output("Geometry", std::move(geometry_set_out));
+}
+
+static void geo_node_points_to_volume_init(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)MEM_callocN(
+ sizeof(NodeGeometryPointsToVolume), __func__);
+ data->resolution_mode = GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT;
+ data->input_type_radius = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
+ node->storage = data;
+
+ bNodeSocket *radius_attribute_socket = nodeFindSocket(node, SOCK_IN, "Radius");
+ bNodeSocketValueString *radius_attribute_socket_value =
+ (bNodeSocketValueString *)radius_attribute_socket->default_value;
+ STRNCPY(radius_attribute_socket_value->value, "radius");
+}
+
+static void geo_node_points_to_volume_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)node->storage;
+ bNodeSocket *voxel_size_socket = nodeFindSocket(node, SOCK_IN, "Voxel Size");
+ bNodeSocket *voxel_amount_socket = nodeFindSocket(node, SOCK_IN, "Voxel Amount");
+ nodeSetSocketAvailability(voxel_amount_socket,
+ data->resolution_mode ==
+ GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT);
+ nodeSetSocketAvailability(
+ voxel_size_socket, data->resolution_mode == GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE);
+
+ update_attribute_input_socket_availabilities(
+ *node, "Radius", (GeometryNodeAttributeInputMode)data->input_type_radius);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_points_to_volume()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_POINTS_TO_VOLUME, "Points to Volume", NODE_CLASS_GEOMETRY, 0);
+ node_type_socket_templates(&ntype, geo_node_points_to_volume_in, geo_node_point_translate_out);
+ node_type_storage(&ntype,
+ "NodeGeometryPointsToVolume",
+ node_free_standard_storage,
+ node_copy_standard_storage);
+ node_type_size(&ntype, 170, 120, 700);
+ node_type_init(&ntype, blender::nodes::geo_node_points_to_volume_init);
+ node_type_update(&ntype, blender::nodes::geo_node_points_to_volume_update);
+ ntype.geometry_node_execute = blender::nodes::geo_node_points_to_volume_exec;
+ ntype.draw_buttons = geo_node_points_to_volume_layout;
+ nodeRegisterType(&ntype);
+}
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 543859aef3f..99f7339a1cc 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
@@ -20,6 +20,9 @@
#include "BKE_subdiv.h"
#include "BKE_subdiv_mesh.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "node_geometry_util.hh"
static bNodeSocketTemplate geo_node_subdivision_surface_in[] = {
@@ -36,6 +39,17 @@ static bNodeSocketTemplate geo_node_subdivision_surface_out[] = {
{-1, ""},
};
+static void geo_node_subdivision_surface_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *UNUSED(ptr))
+{
+#ifndef WITH_OPENSUBDIV
+ uiItemL(layout, IFACE_("Disabled, built without OpenSubdiv"), ICON_ERROR);
+#else
+ UNUSED_VARS(layout);
+#endif
+}
+
namespace blender::nodes {
static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
{
@@ -112,5 +126,6 @@ void register_node_type_geo_subdivision_surface()
node_type_socket_templates(
&ntype, geo_node_subdivision_surface_in, geo_node_subdivision_surface_out);
ntype.geometry_node_execute = blender::nodes::geo_node_subdivision_surface_exec;
+ ntype.draw_buttons = geo_node_subdivision_surface_layout;
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 1fcd1063993..539a7551be9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -14,11 +14,19 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+#endif
+
#include "BLI_math_matrix.h"
#include "DNA_pointcloud_types.h"
+#include "DNA_volume_types.h"
#include "BKE_mesh.h"
+#include "BKE_volume.h"
+
+#include "DEG_depsgraph_query.h"
#include "node_geometry_util.hh"
@@ -109,6 +117,43 @@ static void transform_instances(InstancesComponent &instances,
}
}
+static void transform_volume(Volume *volume,
+ const float3 translation,
+ const float3 rotation,
+ const float3 scale,
+ GeoNodeExecParams &params)
+{
+#ifdef WITH_OPENVDB
+ /* Scaling an axis to zero is not supported for volumes. */
+ const float3 limited_scale = {
+ (scale.x == 0.0f) ? FLT_EPSILON : scale.x,
+ (scale.y == 0.0f) ? FLT_EPSILON : scale.y,
+ (scale.z == 0.0f) ? FLT_EPSILON : scale.z,
+ };
+
+ Main *bmain = DEG_get_bmain(params.depsgraph());
+ BKE_volume_load(volume, bmain);
+
+ float matrix[4][4];
+ loc_eul_size_to_mat4(matrix, translation, rotation, limited_scale);
+
+ openvdb::Mat4s vdb_matrix;
+ memcpy(vdb_matrix.asPointer(), matrix, sizeof(float[4][4]));
+ openvdb::Mat4d vdb_matrix_d{vdb_matrix};
+
+ const int num_grids = BKE_volume_num_grids(volume);
+ for (const int i : IndexRange(num_grids)) {
+ VolumeGrid *volume_grid = BKE_volume_grid_get(volume, i);
+
+ openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(volume, volume_grid, false);
+ openvdb::math::Transform &grid_transform = grid->transform();
+ grid_transform.postMult(vdb_matrix_d);
+ }
+#else
+ UNUSED_VARS(volume, translation, rotation, scale, params);
+#endif
+}
+
static void geo_node_transform_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -131,6 +176,11 @@ static void geo_node_transform_exec(GeoNodeExecParams params)
transform_instances(instances, translation, rotation, scale);
}
+ if (geometry_set.has_volume()) {
+ Volume *volume = geometry_set.get_volume_for_write();
+ transform_volume(volume, translation, rotation, scale, params);
+ }
+
params.set_output("Geometry", std::move(geometry_set));
}
} // namespace blender::nodes
diff --git a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
index c224731ad9f..32fa32a9f13 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
@@ -18,6 +18,9 @@
#include "RNA_enum_types.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "node_geometry_util.hh"
extern "C" {
@@ -39,6 +42,12 @@ static bNodeSocketTemplate geo_node_triangulate_out[] = {
{-1, ""},
};
+static void geo_node_triangulate_layout(uiLayout *layout, bContext *UNUSED(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)
{
node->custom1 = GEO_NODE_TRIANGULATE_QUAD_SHORTEDGE;
@@ -75,5 +84,6 @@ void register_node_type_geo_triangulate()
node_type_socket_templates(&ntype, geo_node_triangulate_in, geo_node_triangulate_out);
node_type_init(&ntype, geo_triangulate_init);
ntype.geometry_node_execute = blender::nodes::geo_node_triangulate_exec;
+ ntype.draw_buttons = geo_node_triangulate_layout;
nodeRegisterType(&ntype);
}
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
new file mode 100644
index 00000000000..54dccb613a1
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
@@ -0,0 +1,171 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "DEG_depsgraph_query.h"
+#ifdef WITH_OPENVDB
+# include <openvdb/tools/GridTransformer.h>
+# include <openvdb/tools/VolumeToMesh.h>
+#endif
+
+#include "node_geometry_util.hh"
+
+#include "BKE_lib_id.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
+#include "BKE_volume.h"
+#include "BKE_volume_to_mesh.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+static bNodeSocketTemplate geo_node_volume_to_mesh_in[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_STRING, N_("Grid")},
+ {SOCK_FLOAT, N_("Voxel Size"), 0.3f, 0.0f, 0.0f, 0.0f, 0.01f, FLT_MAX},
+ {SOCK_FLOAT, N_("Voxel Amount"), 64.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_FLOAT, N_("Threshold"), 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_FLOAT, N_("Adaptivity"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_volume_to_mesh_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+static void geo_node_volume_to_mesh_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+ uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
+}
+
+namespace blender::nodes {
+
+static void geo_node_volume_to_mesh_init(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeGeometryVolumeToMesh *data = (NodeGeometryVolumeToMesh *)MEM_callocN(
+ sizeof(NodeGeometryVolumeToMesh), __func__);
+ data->resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_GRID;
+
+ bNodeSocket *grid_socket = nodeFindSocket(node, SOCK_IN, "Grid");
+ bNodeSocketValueString *grid_socket_value = (bNodeSocketValueString *)grid_socket->default_value;
+ STRNCPY(grid_socket_value->value, "density");
+
+ node->storage = data;
+}
+
+static void geo_node_volume_to_mesh_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeGeometryVolumeToMesh *data = (NodeGeometryVolumeToMesh *)node->storage;
+
+ bNodeSocket *voxel_size_socket = nodeFindSocket(node, SOCK_IN, "Voxel Size");
+ bNodeSocket *voxel_amount_socket = nodeFindSocket(node, SOCK_IN, "Voxel Amount");
+ nodeSetSocketAvailability(voxel_amount_socket,
+ data->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT);
+ nodeSetSocketAvailability(voxel_size_socket,
+ data->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE);
+}
+
+#ifdef WITH_OPENVDB
+
+static void create_mesh_from_volume(GeometrySet &geometry_set_in,
+ GeometrySet &geometry_set_out,
+ GeoNodeExecParams &params)
+{
+ if (!geometry_set_in.has<VolumeComponent>()) {
+ return;
+ }
+
+ const NodeGeometryVolumeToMesh &storage =
+ *(const NodeGeometryVolumeToMesh *)params.node().storage;
+
+ bke::VolumeToMeshResolution resolution;
+ resolution.mode = (VolumeToMeshResolutionMode)storage.resolution_mode;
+ if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT) {
+ resolution.settings.voxel_amount = params.get_input<float>("Voxel Amount");
+ if (resolution.settings.voxel_amount <= 0.0f) {
+ return;
+ }
+ }
+ else if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
+ resolution.settings.voxel_size = params.get_input<float>("Voxel Size");
+ if (resolution.settings.voxel_size <= 0.0f) {
+ return;
+ }
+ }
+
+ const VolumeComponent *component = geometry_set_in.get_component_for_read<VolumeComponent>();
+ const Volume *volume = component->get_for_read();
+ if (volume == nullptr) {
+ return;
+ }
+
+ Main *bmain = DEG_get_bmain(params.depsgraph());
+ BKE_volume_load(const_cast<Volume *>(volume), bmain);
+
+ const std::string grid_name = params.get_input<std::string>("Grid");
+ VolumeGrid *volume_grid = BKE_volume_grid_find(volume, grid_name.c_str());
+ if (volume_grid == nullptr) {
+ return;
+ }
+
+ float threshold = params.get_input<float>("Threshold");
+ float adaptivity = params.get_input<float>("Adaptivity");
+
+ const openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
+ Mesh *mesh = bke::volume_to_mesh(*grid, resolution, threshold, adaptivity);
+ if (mesh == nullptr) {
+ return;
+ }
+ MeshComponent &dst_component = geometry_set_out.get_component_for_write<MeshComponent>();
+ dst_component.replace(mesh);
+}
+
+#endif /* WITH_OPENVDB */
+
+static void geo_node_volume_to_mesh_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set_in = params.extract_input<GeometrySet>("Geometry");
+ GeometrySet geometry_set_out;
+
+#ifdef WITH_OPENVDB
+ create_mesh_from_volume(geometry_set_in, geometry_set_out, params);
+#endif
+
+ params.set_output("Geometry", geometry_set_out);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_volume_to_mesh()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_VOLUME_TO_MESH, "Volume to Mesh", NODE_CLASS_GEOMETRY, 0);
+ node_type_socket_templates(&ntype, geo_node_volume_to_mesh_in, geo_node_volume_to_mesh_out);
+ node_type_storage(
+ &ntype, "NodeGeometryVolumeToMesh", node_free_standard_storage, node_copy_standard_storage);
+ node_type_size(&ntype, 200, 120, 700);
+ node_type_init(&ntype, blender::nodes::geo_node_volume_to_mesh_init);
+ node_type_update(&ntype, blender::nodes::geo_node_volume_to_mesh_update);
+ ntype.geometry_node_execute = blender::nodes::geo_node_volume_to_mesh_exec;
+ ntype.draw_buttons = geo_node_volume_to_mesh_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc
index c693047ff40..f5a0e14f18b 100644
--- a/source/blender/nodes/intern/derived_node_tree.cc
+++ b/source/blender/nodes/intern/derived_node_tree.cc
@@ -91,7 +91,7 @@ DNode &DerivedNodeTree::create_node(const NodeRef &node_ref,
for (int i : node.inputs_.index_range()) {
const InputSocketRef &socket_ref = node_ref.input(i);
DInputSocket &socket = *node.inputs_[i];
-
+ socket.is_multi_input_socket_ = socket_ref.bsocket()->flag & SOCK_MULTI_INPUT;
socket.id_ = UNINITIALIZED_ID;
socket.node_ = &node;
socket.socket_ref_ = &socket_ref;
diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc
index 2e4196af156..c2391667e86 100644
--- a/source/blender/nodes/intern/node_tree_multi_function.cc
+++ b/source/blender/nodes/intern/node_tree_multi_function.cc
@@ -19,6 +19,7 @@
#include "FN_multi_function_network_evaluation.hh"
#include "BLI_color.hh"
+#include "BLI_float2.hh"
#include "BLI_float3.hh"
namespace blender::nodes {
@@ -191,27 +192,58 @@ static void add_implicit_conversion(DataTypeConversions &conversions,
static DataTypeConversions create_implicit_conversions()
{
DataTypeConversions conversions;
- add_implicit_conversion<float, int32_t>(conversions);
+ add_implicit_conversion<float, float2>(conversions);
add_implicit_conversion<float, float3>(conversions);
- add_implicit_conversion<int32_t, float>(conversions);
+ add_implicit_conversion<float, int32_t>(conversions);
add_implicit_conversion<float, bool>(conversions);
- add_implicit_conversion<bool, float>(conversions);
- add_implicit_conversion<float3, float>(
- conversions, "Vector Length", [](float3 a) { return a.length(); });
- add_implicit_conversion<int32_t, float3>(
- conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
- add_implicit_conversion<float3, Color4f>(
- conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
- add_implicit_conversion<Color4f, float3>(
- conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
add_implicit_conversion<float, Color4f>(
conversions, "float to Color4f", [](float a) { return Color4f(a, a, a, 1.0f); });
- add_implicit_conversion<Color4f, float>(
- conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
+
+ add_implicit_conversion<float2, float3>(
+ conversions, "float2 to float3", [](float2 a) { return float3(a.x, a.y, 0.0f); });
+ add_implicit_conversion<float2, float>(
+ conversions, "float2 to float", [](float2 a) { return a.length(); });
+ add_implicit_conversion<float2, int32_t>(
+ conversions, "float2 to int32_t", [](float2 a) { return (int32_t)a.length(); });
+ add_implicit_conversion<float2, bool>(
+ conversions, "float2 to bool", [](float2 a) { return a.length_squared() == 0.0f; });
+ add_implicit_conversion<float2, Color4f>(
+ conversions, "float2 to Color4f", [](float2 a) { return Color4f(a.x, a.y, 0.0f, 1.0f); });
+
add_implicit_conversion<float3, bool>(
conversions, "float3 to boolean", [](float3 a) { return a.length_squared() == 0.0f; });
+ add_implicit_conversion<float3, float>(
+ conversions, "Vector Length", [](float3 a) { return a.length(); });
+ add_implicit_conversion<float3, int32_t>(
+ conversions, "float3 to int32_t", [](float3 a) { return (int)a.length(); });
+ add_implicit_conversion<float3, float2>(conversions);
+ add_implicit_conversion<float3, Color4f>(
+ conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
+
+ add_implicit_conversion<int32_t, bool>(conversions);
+ add_implicit_conversion<int32_t, float>(conversions);
+ add_implicit_conversion<int32_t, float2>(
+ conversions, "int32 to float2", [](int32_t a) { return float2((float)a); });
+ add_implicit_conversion<int32_t, float3>(
+ conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
+
+ add_implicit_conversion<bool, float>(conversions);
+ add_implicit_conversion<bool, int32_t>(conversions);
+ add_implicit_conversion<bool, float2>(
+ conversions, "boolean to float2", [](bool a) { return (a) ? float2(1.0f) : float2(0.0f); });
add_implicit_conversion<bool, float3>(
conversions, "boolean to float3", [](bool a) { return (a) ? float3(1.0f) : float3(0.0f); });
+ add_implicit_conversion<bool, Color4f>(conversions, "boolean to Color4f", [](bool a) {
+ return (a) ? Color4f(1.0f, 1.0f, 1.0f, 1.0f) : Color4f(0.0f, 0.0f, 0.0f, 1.0f);
+ });
+
+ add_implicit_conversion<Color4f, float>(
+ conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
+ add_implicit_conversion<Color4f, float2>(
+ conversions, "Color4f to float2", [](Color4f a) { return float2(a.r, a.g); });
+ add_implicit_conversion<Color4f, float3>(
+ conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
+
return conversions;
}
diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c
index 9669dc6496b..c7c3ced4e56 100644
--- a/source/blender/nodes/intern/node_util.c
+++ b/source/blender/nodes/intern/node_util.c
@@ -281,25 +281,30 @@ static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
return count;
}
-/* find an eligible socket for linking */
+/* Find an eligible socket for linking. */
static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, bNode *node, bNodeSocket *cur)
{
- /* link swapping: try to find a free slot with a matching name */
-
bNodeSocket *first = cur->in_out == SOCK_IN ? node->inputs.first : node->outputs.first;
bNodeSocket *sock;
- sock = cur->next ? cur->next : first; /* wrap around the list end */
+ /* Iterate over all sockets of the target node, to find one that matches the same socket type.
+ * The idea behind this is: When a user connects an input to a socket that is
+ * already linked (and if its not an Multi Input Socket), we try to find a replacement socket for
+ * the link that we try to overwrite and connect that previous link to the new socket. */
+ sock = cur->next ? cur->next : first; /* Wrap around the list end. */
while (sock != cur) {
if (!nodeSocketIsHidden(sock) && node_link_socket_match(sock, cur)) {
- int link_count = node_count_links(ntree, sock);
- /* take +1 into account since we would add a new link */
- if (link_count + 1 <= nodeSocketLinkLimit(sock)) {
- return sock; /* found a valid free socket we can swap to */
- }
+ break;
}
+ sock = sock->next ? sock->next : first; /* Wrap around the list end. */
+ }
- sock = sock->next ? sock->next : first; /* wrap around the list end */
+ if (!nodeSocketIsHidden(sock) && node_link_socket_match(sock, cur)) {
+ int link_count = node_count_links(ntree, sock);
+ /* Take +1 into account since we would add a new link. */
+ if (link_count + 1 <= nodeSocketLinkLimit(sock)) {
+ return sock; /* Found a valid free socket we can swap to. */
+ }
}
return NULL;
}
@@ -309,7 +314,6 @@ void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link)
bNodeSocket *sock = link->tosock;
bNodeLink *tlink, *tlink_next;
- /* inputs can have one link only, outputs can have unlimited links */
if (node != link->tonode) {
return;
}
diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c
index 96a0be6babc..2091a8bf10e 100644
--- a/source/blender/nodes/texture/node_texture_util.c
+++ b/source/blender/nodes/texture/node_texture_util.c
@@ -146,7 +146,7 @@ void tex_output(bNode *node,
}
if (!out->data) {
- /* Freed in tex_end_exec (node.c) */
+ /* Freed in tex_end_exec (node.cc) */
dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
}
else {
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 38122c45ef1..e9499818f64 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -293,7 +293,7 @@ static int bpy_bmesh_select_mode_set(BPy_BMesh *self, PyObject *value)
return -1;
}
if (flag == 0) {
- PyErr_SetString(PyExc_TypeError, "bm.select_mode: cant assignt an empty value");
+ PyErr_SetString(PyExc_TypeError, "bm.select_mode: can't assign an empty value");
return -1;
}
@@ -1079,7 +1079,12 @@ PyDoc_STRVAR(
" :arg cage: Get the mesh as a deformed cage.\n"
" :type cage: boolean\n"
" :arg face_normals: Calculate face normals.\n"
- " :type face_normals: boolean\n");
+ " :type face_normals: boolean\n"
+ "\n"
+ " .. deprecated:: 2.93\n"
+ "\n"
+ " The deform parameter is deprecated, assumed to be True, and will be removed in version "
+ "3.0.\n");
static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject *kw)
{
static const char *kwlist[] = {"object", "depsgraph", "deform", "cage", "face_normals", NULL};
@@ -1120,45 +1125,36 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject
return NULL;
}
+ if (use_deform == false) {
+ PyErr_WarnEx(PyExc_FutureWarning,
+ "from_object(...): the deform parameter is deprecated, assumed to be True, and "
+ "will be removed in version 3.0",
+ 1);
+ }
+
const bool use_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
scene_eval = DEG_get_evaluated_scene(depsgraph);
ob_eval = DEG_get_evaluated_object(depsgraph, ob);
bool need_free = false;
/* Write the display mesh into the dummy mesh */
- if (use_deform) {
- if (use_render) {
- if (use_cage) {
- PyErr_SetString(PyExc_ValueError,
- "from_object(...): cage arg is unsupported when dependency graph "
- "evaluation mode is RENDER");
- return NULL;
- }
-
- me_eval = BKE_mesh_new_from_object(depsgraph, ob_eval, true);
- need_free = true;
- }
- else {
- if (use_cage) {
- me_eval = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &data_masks);
- }
- else {
- me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &data_masks);
- }
- }
- }
- else {
- /* !use_deform */
+ if (use_render) {
if (use_cage) {
PyErr_SetString(PyExc_ValueError,
- "from_object(...): cage arg is unsupported when deform=False");
+ "from_object(...): cage arg is unsupported when dependency graph "
+ "evaluation mode is RENDER");
return NULL;
}
- if (use_render) {
- me_eval = mesh_create_eval_no_deform_render(depsgraph, scene_eval, ob, &data_masks);
+
+ me_eval = BKE_mesh_new_from_object(depsgraph, ob_eval, true);
+ need_free = true;
+ }
+ else {
+ if (use_cage) {
+ me_eval = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &data_masks);
}
else {
- me_eval = mesh_create_eval_no_deform(depsgraph, scene_eval, ob, &data_masks);
+ me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &data_masks);
}
}
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index d944cb435d0..ec6b8c54ac0 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -865,11 +865,11 @@ bool PyC_NameSpace_ImportArray(PyObject *py_dict, const char *imports[])
}
/* restore MUST be called after this */
-void PyC_MainModule_Backup(PyObject **main_mod)
+void PyC_MainModule_Backup(PyObject **r_main_mod)
{
PyObject *modules = PyImport_GetModuleDict();
- *main_mod = PyDict_GetItemString(modules, "__main__");
- Py_XINCREF(*main_mod); /* don't free */
+ *r_main_mod = PyDict_GetItemString(modules, "__main__");
+ Py_XINCREF(*r_main_mod); /* don't free */
}
void PyC_MainModule_Restore(PyObject *main_mod)
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index f0875b82c3c..358123657c7 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -85,7 +85,7 @@ PyObject *PyC_DefaultNameSpace(const char *filename);
void PyC_RunQuicky(const char *filepath, int n, ...);
bool PyC_NameSpace_ImportArray(PyObject *py_dict, const char *imports[]);
-void PyC_MainModule_Backup(PyObject **main_mod);
+void PyC_MainModule_Backup(PyObject **r_main_mod);
void PyC_MainModule_Restore(PyObject *main_mod);
void PyC_SetHomePath(const char *py_path_bundle);
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index 526b96f8584..b2603c75c3f 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -169,12 +169,12 @@ static PyObject *py_shader_uniform_block_from_name(BPyGPUShader *self, PyObject
return PyLong_FromLong(uniform);
}
-static bool py_shader_uniform_vector_imp(PyObject *args,
- int elem_size,
- int *r_location,
- int *r_length,
- int *r_count,
- Py_buffer *r_pybuffer)
+static bool py_shader_uniform_vector_impl(PyObject *args,
+ int elem_size,
+ int *r_location,
+ int *r_length,
+ int *r_count,
+ Py_buffer *r_pybuffer)
{
PyObject *buffer;
@@ -223,7 +223,7 @@ static PyObject *py_shader_uniform_vector_float(BPyGPUShader *self, PyObject *ar
Py_buffer pybuffer;
- if (!py_shader_uniform_vector_imp(args, sizeof(float), &location, &length, &count, &pybuffer)) {
+ if (!py_shader_uniform_vector_impl(args, sizeof(float), &location, &length, &count, &pybuffer)) {
return NULL;
}
@@ -244,7 +244,7 @@ static PyObject *py_shader_uniform_vector_int(BPyGPUShader *self, PyObject *args
Py_buffer pybuffer;
- if (!py_shader_uniform_vector_imp(args, sizeof(int), &location, &length, &count, &pybuffer)) {
+ if (!py_shader_uniform_vector_impl(args, sizeof(int), &location, &length, &count, &pybuffer)) {
return NULL;
}
@@ -570,9 +570,6 @@ PyDoc_STRVAR(
" ``GL_ARB_texture_gather``, ``GL_ARB_texture_cube_map_array``\n"
" and ``GL_ARB_shader_draw_parameters``.\n"
"\n"
- " To debug shaders, use the ``--debug-gpu-shaders`` command line option\n"
- " to see full GLSL shader compilation and linking errors.\n"
- "\n"
" For drawing user interface elements and gizmos, use\n"
" ``fragOutput = blender_srgb_to_framebuffer_space(fragOutput)``\n"
" to transform the output sRGB colors to the frame-buffer color-space.\n"
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index 02ab001dbf6..c7e195b586d 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -424,11 +424,6 @@ static PyGetSetDef bpy_app_getsets[] = {
bpy_app_debug_set,
bpy_app_debug_doc,
(void *)G_DEBUG_SIMDATA},
- {"debug_gpumem",
- bpy_app_debug_get,
- bpy_app_debug_set,
- bpy_app_debug_doc,
- (void *)G_DEBUG_GPU_MEM},
{"debug_io", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG_IO},
{"use_event_simulate",
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index 1e81621246e..8ecee9b3f2e 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -286,7 +286,7 @@ void BPY_app_handlers_reset(const short do_all)
}
else {
/* remove */
- /* PySequence_DelItem(ls, i); */ /* more obvious buw slower */
+ /* PySequence_DelItem(ls, i); */ /* more obvious but slower */
PyList_SetSlice(ls, i, i + 1, NULL);
}
}
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 64e992bd76f..c4789407e4e 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -341,12 +341,20 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
}
}
- /* Without this the `sys.stdout` may be set to 'ascii'
- * (it is on my system at least), where printing unicode values will raise
- * an error, this is highly annoying, another stumbling block for developers,
- * so use a more relaxed error handler and enforce utf-8 since the rest of
- * Blender is utf-8 too - campbell */
- Py_SetStandardStreamEncoding("utf-8", "surrogateescape");
+ /* Force `utf-8` on all platforms, since this is what's used for Blender's internal strings,
+ * providing consistent encoding behavior across all Blender installations.
+ *
+ * This also uses the `surrogateescape` error handler ensures any unexpected bytes are escaped
+ * instead of raising an error.
+ *
+ * Without this `sys.getfilesystemencoding()` and `sys.stdout` for example may be set to ASCII
+ * or some other encoding - where printing some `utf-8` values will raise an error.
+ *
+ * This can cause scripts to fail entirely on some systems.
+ *
+ * This assignment is the equivalent of enabling the `PYTHONUTF8` environment variable.
+ * See `PEP-540` for details on exactly what this changes. */
+ Py_UTF8Mode = 1;
/* Suppress error messages when calculating the module search path.
* While harmless, it's noisy. */
diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c
index 8e5a6dc530b..03d51b2fd59 100644
--- a/source/blender/python/intern/bpy_interface_atexit.c
+++ b/source/blender/python/intern/bpy_interface_atexit.c
@@ -42,7 +42,7 @@ static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyOb
}
static PyMethodDef meth_bpy_atexit = {"bpy_atexit", (PyCFunction)bpy_atexit, METH_NOARGS, NULL};
-static PyObject *func_bpy_atregister = NULL; /* borrowed referebce, atexit holds */
+static PyObject *func_bpy_atregister = NULL; /* borrowed reference, `atexit` holds. */
static void atexit_func_call(const char *func_name, PyObject *atexit_func_arg)
{
diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c
index c6f0fbd3a2b..39d1fba2dc9 100644
--- a/source/blender/python/intern/bpy_library_load.c
+++ b/source/blender/python/intern/bpy_library_load.c
@@ -173,7 +173,7 @@ static PyTypeObject bpy_lib_Type = {
PyDoc_STRVAR(
bpy_lib_load_doc,
- ".. method:: load(filepath, link=False, relative=False)\n"
+ ".. method:: load(filepath, link=False, relative=False, assets_only=False)\n"
"\n"
" Returns a context manager which exposes 2 library objects on entering.\n"
" Each object has attributes matching bpy.data which are lists of strings to be linked.\n"
@@ -183,18 +183,28 @@ PyDoc_STRVAR(
" :arg link: When False reference to the original file is lost.\n"
" :type link: bool\n"
" :arg relative: When True the path is stored relative to the open blend file.\n"
- " :type relative: bool\n");
+ " :type relative: bool\n"
+ " :arg assets_only: If True, only list data-blocks marked as assets.\n"
+ " :type assets_only: bool\n");
static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
Main *bmain = CTX_data_main(BPY_context_get());
BPy_Library *ret;
const char *filename = NULL;
- bool is_rel = false, is_link = false;
-
- static const char *_keywords[] = {"filepath", "link", "relative", NULL};
- static _PyArg_Parser _parser = {"s|O&O&:load", _keywords, 0};
- if (!_PyArg_ParseTupleAndKeywordsFast(
- args, kw, &_parser, &filename, PyC_ParseBool, &is_link, PyC_ParseBool, &is_rel)) {
+ bool is_rel = false, is_link = false, use_assets_only = false;
+
+ static const char *_keywords[] = {"filepath", "link", "relative", "assets_only", NULL};
+ static _PyArg_Parser _parser = {"s|O&O&O&:load", _keywords, 0};
+ if (!_PyArg_ParseTupleAndKeywordsFast(args,
+ kw,
+ &_parser,
+ &filename,
+ PyC_ParseBool,
+ &is_link,
+ PyC_ParseBool,
+ &is_rel,
+ PyC_ParseBool,
+ &use_assets_only)) {
return NULL;
}
@@ -205,7 +215,8 @@ static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *
BLI_path_abs(ret->abspath, BKE_main_blendfile_path(bmain));
ret->blo_handle = NULL;
- ret->flag = ((is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0));
+ ret->flag = ((is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0) |
+ (use_assets_only ? FILE_ASSETS_ONLY : 0));
ret->dict = _PyDict_NewPresized(MAX_LIBARRAY);
@@ -218,7 +229,8 @@ static PyObject *_bpy_names(BPy_Library *self, int blocktype)
LinkNode *l, *names;
int totnames;
- names = BLO_blendhandle_get_datablock_names(self->blo_handle, blocktype, &totnames);
+ names = BLO_blendhandle_get_datablock_names(
+ self->blo_handle, blocktype, (self->flag & FILE_ASSETS_ONLY) != 0, &totnames);
list = PyList_New(totnames);
if (names) {
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index a2125a5dff9..39ba8448795 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -605,7 +605,7 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr,
if (*r_prop_eul_order) {
const short order = RNA_property_enum_get(ptr, *r_prop_eul_order);
- /* Could be quat or axisangle. */
+ /* Could be quaternion or axis-angle. */
if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) {
return order;
}
@@ -5051,7 +5051,7 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key
{
Py_ssize_t key_len_ssize_t;
const char *key = _PyUnicode_AsStringAndSize(key_ob, &key_len_ssize_t);
- const int key_len = (int)key_len_ssize_t; /* Comare with same type. */
+ const int key_len = (int)key_len_ssize_t; /* Compare with same type. */
char name[256], *nameptr;
int namelen;
@@ -5094,7 +5094,7 @@ static bool foreach_attr_type(BPy_PropertyRNA *self,
*r_attr_tot = 0;
*r_attr_signed = false;
- /* Note: this is fail with zero length lists, so don't let this get caled in that case. */
+ /* NOTE: this is fail with zero length lists, so don't let this get called in that case. */
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
prop = RNA_struct_find_property(&itemptr, attr);
if (prop) {
@@ -8737,15 +8737,17 @@ void pyrna_free_types(void)
RNA_PROP_END;
}
-/* Note! MemLeak XXX
+/**
+ * \warning memory leak!
*
* There is currently a bug where moving the registration of a Python class does
- * not properly manage reference-counts from the Python class. As the srna owns
+ * not properly manage reference-counts from the Python class. As the `srna` owns
* the Python class this should not be so tricky, but changing the references as
* you'd expect when changing ownership crashes blender on exit so I had to comment out
- * the decref. This is not so bad because the leak only happens when re-registering (hold F8)
+ * the #Py_DECREF. This is not so bad because the leak only happens when re-registering
+ * (continuously running `SCRIPT_OT_reload`).
* - Should still be fixed - Campbell
- * */
+ */
PyDoc_STRVAR(pyrna_register_class_doc,
".. method:: register_class(cls)\n"
"\n"
diff --git a/source/blender/render/RE_engine.h b/source/blender/render/RE_engine.h
index 1af40ac760b..c31a41f66d5 100644
--- a/source/blender/render/RE_engine.h
+++ b/source/blender/render/RE_engine.h
@@ -64,6 +64,7 @@ extern "C" {
#define RE_USE_SPHERICAL_STEREO 128
#define RE_USE_STEREO_VIEWPORT 256
#define RE_USE_GPU_CONTEXT 512
+#define RE_USE_CUSTOM_FREESTYLE 1024
/* RenderEngine.flag */
#define RE_ENGINE_ANIMATION 1
diff --git a/source/blender/render/RE_multires_bake.h b/source/blender/render/RE_multires_bake.h
index fd200e85719..42ee2c57fbb 100644
--- a/source/blender/render/RE_multires_bake.h
+++ b/source/blender/render/RE_multires_bake.h
@@ -53,7 +53,7 @@ typedef struct MultiresBakeRender {
int baked_objects, baked_faces;
int raytrace_structure; /* Optimization structure to be used for AO baking */
- int octree_resolution; /* Reslution of octotree when using octotree optimization structure */
+ int octree_resolution; /* Resolution of octree when using octree optimization structure */
int threads; /* Number of threads to be used for baking */
float user_scale; /* User scale used to scale displacement when baking derivative map. */
diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h
index 3e73ac77fc6..688709d55f3 100644
--- a/source/blender/render/RE_pipeline.h
+++ b/source/blender/render/RE_pipeline.h
@@ -252,13 +252,11 @@ void RE_ChangeModeFlag(struct Render *re, int flag, bool clear);
struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */
void RE_SetOverrideCamera(struct Render *re, struct Object *cam_ob);
void RE_SetCamera(struct Render *re, struct Object *cam_ob);
-void RE_SetWindow(struct Render *re, const rctf *viewplane, float clip_start, float clip_end);
-void RE_SetOrtho(struct Render *re, const rctf *viewplane, float clip_start, float clip_end);
/* get current view and window transform */
void RE_GetViewPlane(struct Render *re, rctf *r_viewplane, rcti *r_disprect);
-/* set the render threads based on the command-line and autothreads setting */
+/* Set the render threads based on the command-line and auto-threads setting. */
void RE_init_threadcount(Render *re);
bool RE_WriteRenderViewsImage(struct ReportList *reports,
diff --git a/source/blender/render/intern/initrender.c b/source/blender/render/intern/initrender.c
index fb7f7270c13..3494aa06833 100644
--- a/source/blender/render/intern/initrender.c
+++ b/source/blender/render/intern/initrender.c
@@ -172,28 +172,16 @@ struct Object *RE_GetCamera(Render *re)
return BKE_camera_multiview_render(re->scene, camera, re->viewname);
}
-static void re_camera_params_get(Render *re, CameraParams *params)
-{
- copy_m4_m4(re->winmat, params->winmat);
-
- re->clip_start = params->clip_start;
- re->clip_end = params->clip_end;
-
- re->viewplane = params->viewplane;
-}
-
void RE_SetOverrideCamera(Render *re, Object *cam_ob)
{
re->camera_override = cam_ob;
}
-static void re_camera_params_stereo3d(Render *re, CameraParams *params, Object *cam_ob)
-{
- BKE_camera_multiview_params(&re->r, params, cam_ob, re->viewname);
-}
-
-/* call this after InitState() */
-/* per render, there's one persistent viewplane. Parts will set their own viewplanes */
+/**
+ * Per render, there's one persistent view-plane. Parts will set their own view-planes.
+ *
+ * \note call this after #RE_InitState().
+ */
void RE_SetCamera(Render *re, Object *cam_ob)
{
CameraParams params;
@@ -201,14 +189,17 @@ void RE_SetCamera(Render *re, Object *cam_ob)
/* setup parameters */
BKE_camera_params_init(&params);
BKE_camera_params_from_object(&params, cam_ob);
- re_camera_params_stereo3d(re, &params, cam_ob);
+ BKE_camera_multiview_params(&re->r, &params, cam_ob, re->viewname);
/* compute matrix, viewplane, .. */
BKE_camera_params_compute_viewplane(&params, re->winx, re->winy, re->r.xasp, re->r.yasp);
BKE_camera_params_compute_matrix(&params);
/* extract results */
- re_camera_params_get(re, &params);
+ copy_m4_m4(re->winmat, params.winmat);
+ re->clip_start = params.clip_start;
+ re->clip_end = params.clip_end;
+ re->viewplane = params.viewplane;
}
void RE_GetCameraWindow(struct Render *re, struct Object *camera, float r_winmat[4][4])
@@ -241,6 +232,19 @@ void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_modelmat
BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, r_modelmat);
}
+void RE_GetViewPlane(Render *re, rctf *r_viewplane, rcti *r_disprect)
+{
+ *r_viewplane = re->viewplane;
+
+ /* make disprect zero when no border render, is needed to detect changes in 3d view render */
+ if (re->r.mode & R_BORDER) {
+ *r_disprect = re->disprect;
+ }
+ else {
+ BLI_rcti_init(r_disprect, 0, 0, 0, 0);
+ }
+}
+
/* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
void RE_parts_free(Render *re)
diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c
index a4f68419c67..1859886f563 100644
--- a/source/blender/render/intern/multires_bake.c
+++ b/source/blender/render/intern/multires_bake.c
@@ -768,7 +768,7 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
if (ss_lvl > 0) {
smd.levels = smd.renderLevels = ss_lvl;
- smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
+ smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES;
smd.quality = 3;
height_data->ssdm = subsurf_make_derived_from_derived(
diff --git a/source/blender/render/intern/pipeline.c b/source/blender/render/intern/pipeline.c
index 4628a5a132b..0a8b8f24614 100644
--- a/source/blender/render/intern/pipeline.c
+++ b/source/blender/render/intern/pipeline.c
@@ -983,53 +983,6 @@ void render_update_anim_renderdata(Render *re, RenderData *rd, ListBase *render_
BLI_duplicatelist(&re->r.views, &rd->views);
}
-void RE_SetWindow(Render *re, const rctf *viewplane, float clip_start, float clip_end)
-{
- /* re->ok flag? */
-
- re->viewplane = *viewplane;
- re->clip_start = clip_start;
- re->clip_end = clip_end;
-
- perspective_m4(re->winmat,
- re->viewplane.xmin,
- re->viewplane.xmax,
- re->viewplane.ymin,
- re->viewplane.ymax,
- re->clip_start,
- re->clip_end);
-}
-
-void RE_SetOrtho(Render *re, const rctf *viewplane, float clip_start, float clip_end)
-{
- /* re->ok flag? */
-
- re->viewplane = *viewplane;
- re->clip_start = clip_start;
- re->clip_end = clip_end;
-
- orthographic_m4(re->winmat,
- re->viewplane.xmin,
- re->viewplane.xmax,
- re->viewplane.ymin,
- re->viewplane.ymax,
- re->clip_start,
- re->clip_end);
-}
-
-void RE_GetViewPlane(Render *re, rctf *r_viewplane, rcti *r_disprect)
-{
- *r_viewplane = re->viewplane;
-
- /* make disprect zero when no border render, is needed to detect changes in 3d view render */
- if (re->r.mode & R_BORDER) {
- *r_disprect = re->disprect;
- }
- else {
- BLI_rcti_init(r_disprect, 0, 0, 0, 0);
- }
-}
-
/* image and movie output has to move to either imbuf or kernel */
void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
{
@@ -2018,7 +1971,7 @@ void RE_RenderFrame(Render *re,
if (write_still && !G.is_break) {
if (BKE_imtype_is_movie(rd.im_format.imtype)) {
/* operator checks this but in case its called from elsewhere */
- printf("Error: cant write single images with a movie format!\n");
+ printf("Error: can't write single images with a movie format!\n");
}
else {
char name[FILE_MAX];
@@ -2055,12 +2008,39 @@ void RE_RenderFrame(Render *re,
}
#ifdef WITH_FREESTYLE
+
+/* Not freestyle specific, currently only used by free-style. */
+static void change_renderdata_engine(Render *re, const char *new_engine)
+{
+ if (!STREQ(re->r.engine, new_engine)) {
+ if (re->engine) {
+ RE_engine_free(re->engine);
+ re->engine = NULL;
+ }
+ BLI_strncpy(re->r.engine, new_engine, sizeof(re->r.engine));
+ }
+}
+
+static bool use_eevee_for_freestyle_render(Render *re)
+{
+ RenderEngineType *type = RE_engines_find(re->r.engine);
+ return !(type->flag & RE_USE_CUSTOM_FREESTYLE);
+}
+
void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render)
{
re->result_ok = 0;
if (render_init_from_main(re, &scene->r, bmain, scene, NULL, NULL, 0, 0)) {
if (render) {
+ char scene_engine[32];
+ BLI_strncpy(scene_engine, re->r.engine, sizeof(scene_engine));
+ if (use_eevee_for_freestyle_render(re)) {
+ change_renderdata_engine(re, RE_engine_id_BLENDER_EEVEE);
+ }
+
do_render_3d(re);
+
+ change_renderdata_engine(re, scene_engine);
}
}
re->result_ok = 1;
@@ -2357,7 +2337,7 @@ static int do_write_image_or_movie(Render *re,
printf(" (Saving: %s)\n", name);
fputc('\n', stdout);
- fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
+ fflush(stdout);
return ok;
}
@@ -2757,7 +2737,7 @@ void RE_init_threadcount(Render *re)
void RE_layer_load_from_file(
RenderLayer *layer, ReportList *reports, const char *filename, int x, int y)
{
- /* OCIO_TODO: assume layer was saved in defaule color space */
+ /* OCIO_TODO: assume layer was saved in default color space */
ImBuf *ibuf = IMB_loadiffname(filename, IB_rect, NULL);
RenderPass *rpass = NULL;
diff --git a/source/blender/render/intern/render_result.c b/source/blender/render/intern/render_result.c
index f135adc9f05..f73a200f3c6 100644
--- a/source/blender/render/intern/render_result.c
+++ b/source/blender/render/intern/render_result.c
@@ -443,7 +443,7 @@ RenderResult *render_result_new(
}
FOREACH_VIEW_LAYER_TO_RENDER_END;
- /* previewrender doesn't do layers, so we make a default one */
+ /* Preview-render doesn't do layers, so we make a default one. */
if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) {
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
diff --git a/source/blender/render/intern/render_types.h b/source/blender/render/intern/render_types.h
index 6be5fb4792c..7a4374dcf7c 100644
--- a/source/blender/render/intern/render_types.h
+++ b/source/blender/render/intern/render_types.h
@@ -103,7 +103,7 @@ struct Render {
/* Camera transform, only used by Freestyle. */
float winmat[4][4];
- /* clippping */
+ /* Clipping. */
float clip_start;
float clip_end;
diff --git a/source/blender/render/intern/texture_image.c b/source/blender/render/intern/texture_image.c
index 5614318afbb..0299315beaf 100644
--- a/source/blender/render/intern/texture_image.c
+++ b/source/blender/render/intern/texture_image.c
@@ -630,7 +630,7 @@ static void boxsample(ImBuf *ibuf,
const short imapextend)
{
/* Sample box, performs clip. minx etc are in range 0.0 - 1.0 .
- * Enlarge with antialiased edges of pixels.
+ * Enlarge with anti-aliased edges of pixels.
* If variable 'imaprepeat' has been set, the
* clipped-away parts are sampled as well.
*/
diff --git a/source/blender/render/intern/texture_procedural.c b/source/blender/render/intern/texture_procedural.c
index a98f29a705d..b0ab20de10d 100644
--- a/source/blender/render/intern/texture_procedural.c
+++ b/source/blender/render/intern/texture_procedural.c
@@ -77,7 +77,7 @@ void RE_texture_rng_exit(void)
/* ------------------------------------------------------------------------- */
-/* this allows colorbanded textures to control normals as well */
+/* This allows color-banded textures to control normals as well. */
static void tex_normal_derivate(const Tex *tex, TexResult *texres)
{
if (tex->flag & TEX_COLORBAND) {
@@ -167,7 +167,7 @@ static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
/* ------------------------------------------------------------------------- */
/* ************************************************************************* */
-/* newnoise: all noisebased types now have different noisebases to choose from */
+/* newnoise: all noise-based types now have different noise-bases to choose from. */
static int clouds(const Tex *tex, const float texvec[3], TexResult *texres)
{
@@ -1059,7 +1059,7 @@ static void do_2d_mapping(
dyt[2] *= 0.5f;
}
- /* if area, then reacalculate dxt[] and dyt[] */
+ /* If area, then recalculate `dxt[]` and `dyt[]` */
if (areaflag) {
fx = area[0];
fy = area[1];
diff --git a/source/blender/render/intern/zbuf.c b/source/blender/render/intern/zbuf.c
index d74ab330dc2..33af3bbaf29 100644
--- a/source/blender/render/intern/zbuf.c
+++ b/source/blender/render/intern/zbuf.c
@@ -166,7 +166,7 @@ static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
}
for (y = my2; y >= my0; y--, xs0 += dx0) {
- /* xs0 is the xcoord! */
+ /* xs0 is the X-coordinate! */
span[y] = xs0;
}
}
diff --git a/source/blender/sequencer/SEQ_render.h b/source/blender/sequencer/SEQ_render.h
index 6f6d195126b..54584824da8 100644
--- a/source/blender/sequencer/SEQ_render.h
+++ b/source/blender/sequencer/SEQ_render.h
@@ -51,7 +51,7 @@ typedef struct SeqRenderData {
bool is_proxy_render;
bool is_prefetch_render;
int view_id;
- /* ID of task for asigning temp cache entries to particular task(thread, etc.) */
+ /* ID of task for assigning temp cache entries to particular task(thread, etc.) */
eSeqTaskId task_id;
/* special case for OpenGL render */
diff --git a/source/blender/sequencer/SEQ_select.h b/source/blender/sequencer/SEQ_select.h
index 5a65f9c0d8c..abd56ef3af7 100644
--- a/source/blender/sequencer/SEQ_select.h
+++ b/source/blender/sequencer/SEQ_select.h
@@ -32,8 +32,8 @@ struct Sequence;
struct Sequence *SEQ_select_active_get(struct Scene *scene);
int SEQ_select_active_get_pair(struct Scene *scene,
- struct Sequence **seq_act,
- struct Sequence **seq_other);
+ struct Sequence **r_seq_act,
+ struct Sequence **r_seq_other);
void SEQ_select_active_set(struct Scene *scene, struct Sequence *seq);
#ifdef __cplusplus
diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c
index 344b5af26aa..290ee185865 100644
--- a/source/blender/sequencer/intern/image_cache.c
+++ b/source/blender/sequencer/intern/image_cache.c
@@ -166,7 +166,7 @@ typedef struct SeqCacheKey {
float timeline_frame; /* Only for reference - used for freeing when cache is full. */
float cost; /* In short: render time(s) divided by playback frame duration(s) */
bool is_temp_cache; /* this cache entry will be freed before rendering next frame */
- /* ID of task for asigning temp cache entries to particular task(thread, etc.) */
+ /* ID of task for assigning temp cache entries to particular task(thread, etc.) */
eSeqTaskId task_id;
int type;
} SeqCacheKey;
@@ -824,16 +824,59 @@ static void seq_cache_valfree(void *val)
BLI_mempool_free(item->cache_owner->items_pool, item);
}
-static void seq_cache_put_ex(SeqCache *cache, SeqCacheKey *key, ImBuf *ibuf)
+static int get_stored_types_flag(Scene *scene, SeqCacheKey *key)
{
+ int flag;
+ if (key->seq->cache_flag & SEQ_CACHE_OVERRIDE) {
+ flag = key->seq->cache_flag;
+ }
+ else {
+ flag = scene->ed->cache_flag;
+ }
+
+ /* SEQ_CACHE_STORE_FINAL_OUT can not be overridden by strip cache */
+ flag |= (scene->ed->cache_flag & SEQ_CACHE_STORE_FINAL_OUT);
+
+ return flag;
+}
+
+static void seq_cache_put_ex(Scene *scene, SeqCacheKey *key, ImBuf *ibuf)
+{
+ SeqCache *cache = seq_cache_get_from_scene(scene);
SeqCacheItem *item;
item = BLI_mempool_alloc(cache->items_pool);
item->cache_owner = cache;
item->ibuf = ibuf;
+ const int stored_types_flag = get_stored_types_flag(scene, key);
+
+ /* Item stored for later use. */
+ if (stored_types_flag & key->type) {
+ key->is_temp_cache = false;
+ key->link_prev = cache->last_key;
+ }
+
+ /* Store pointer to last cached key. */
+ SeqCacheKey *temp_last_key = cache->last_key;
+
if (BLI_ghash_reinsert(cache->hash, key, item, seq_cache_keyfree, seq_cache_valfree)) {
IMB_refImBuf(ibuf);
- cache->last_key = key;
+
+ if (!key->is_temp_cache) {
+ cache->last_key = key;
+ }
+ }
+
+ /* Set last_key's reference to this key so we can look up chain backwards.
+ * Item is already put in cache, so cache->last_key points to current key.
+ */
+ if (!key->is_temp_cache && temp_last_key) {
+ temp_last_key->link_next = cache->last_key;
+ }
+
+ /* Reset linking. */
+ if (key->type == SEQ_CACHE_STORE_FINAL_OUT) {
+ cache->last_key = NULL;
}
}
@@ -1095,6 +1138,35 @@ static void seq_cache_create(Main *bmain, Scene *scene)
BLI_mutex_unlock(&cache_create_lock);
}
+static void seq_cache_populate_key(SeqCacheKey *key,
+ const SeqRenderData *context,
+ Sequence *seq,
+ const float timeline_frame,
+ const int type)
+{
+ key->cache_owner = seq_cache_get_from_scene(context->scene);
+ key->seq = seq;
+ key->context = *context;
+ key->frame_index = seq_cache_timeline_frame_to_frame_index(seq, timeline_frame, type);
+ key->timeline_frame = timeline_frame;
+ key->type = type;
+ key->link_prev = NULL;
+ key->link_next = NULL;
+ key->is_temp_cache = true;
+ key->task_id = context->task_id;
+}
+
+static SeqCacheKey *seq_cache_allocate_key(SeqCache *cache,
+ const SeqRenderData *context,
+ Sequence *seq,
+ const float timeline_frame,
+ const int type)
+{
+ SeqCacheKey *key = BLI_mempool_alloc(cache->keys_pool);
+ seq_cache_populate_key(key, context, seq, timeline_frame, type);
+ return key;
+}
+
/* ***************************** API ****************************** */
void seq_cache_free_temp_cache(Scene *scene, short id, int timeline_frame)
@@ -1243,8 +1315,7 @@ void seq_cache_cleanup_sequence(Scene *scene,
struct ImBuf *seq_cache_get(const SeqRenderData *context,
Sequence *seq,
float timeline_frame,
- int type,
- bool skip_disk_cache)
+ int type)
{
if (context->skip_cache || context->is_proxy_render || !seq) {
@@ -1274,11 +1345,7 @@ struct ImBuf *seq_cache_get(const SeqRenderData *context,
/* Try RAM cache: */
if (cache && seq) {
- key.seq = seq;
- key.context = *context;
- key.frame_index = seq_cache_timeline_frame_to_frame_index(seq, timeline_frame, type);
- key.type = type;
-
+ seq_cache_populate_key(&key, context, seq, timeline_frame, type);
ibuf = seq_cache_get_ex(cache, &key);
}
seq_cache_unlock(scene);
@@ -1288,7 +1355,7 @@ struct ImBuf *seq_cache_get(const SeqRenderData *context,
}
/* Try disk cache: */
- if (!skip_disk_cache && seq_disk_cache_is_enabled(context->bmain)) {
+ if (seq_disk_cache_is_enabled(context->bmain)) {
if (cache->disk_cache == NULL) {
seq_disk_cache_create(context->bmain, context->scene);
}
@@ -1296,25 +1363,23 @@ struct ImBuf *seq_cache_get(const SeqRenderData *context,
BLI_mutex_lock(&cache->disk_cache->read_write_mutex);
ibuf = seq_disk_cache_read_file(cache->disk_cache, &key);
BLI_mutex_unlock(&cache->disk_cache->read_write_mutex);
- if (ibuf) {
- if (key.type == SEQ_CACHE_STORE_FINAL_OUT) {
- seq_cache_put_if_possible(context, seq, timeline_frame, type, ibuf, true);
- }
- else {
- seq_cache_put(context, seq, timeline_frame, type, ibuf, true);
- }
+
+ if (ibuf == NULL) {
+ return NULL;
+ }
+
+ /* Store read image in RAM. Only recycle item for final type. */
+ if (key.type != SEQ_CACHE_STORE_FINAL_OUT || seq_cache_recycle_item(scene)) {
+ SeqCacheKey *new_key = seq_cache_allocate_key(cache, context, seq, timeline_frame, type);
+ seq_cache_put_ex(scene, new_key, ibuf);
}
}
return ibuf;
}
-bool seq_cache_put_if_possible(const SeqRenderData *context,
- Sequence *seq,
- float timeline_frame,
- int type,
- ImBuf *ibuf,
- bool skip_disk_cache)
+bool seq_cache_put_if_possible(
+ const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *ibuf)
{
Scene *scene = context->scene;
@@ -1329,7 +1394,7 @@ bool seq_cache_put_if_possible(const SeqRenderData *context,
}
if (seq_cache_recycle_item(scene)) {
- seq_cache_put(context, seq, timeline_frame, type, ibuf, skip_disk_cache);
+ seq_cache_put(context, seq, timeline_frame, type, ibuf);
return true;
}
@@ -1338,12 +1403,8 @@ bool seq_cache_put_if_possible(const SeqRenderData *context,
return false;
}
-void seq_cache_put(const SeqRenderData *context,
- Sequence *seq,
- float timeline_frame,
- int type,
- ImBuf *i,
- bool skip_disk_cache)
+void seq_cache_put(
+ const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *i)
{
if (i == NULL || context->skip_cache || context->is_proxy_render || !seq) {
return;
@@ -1359,7 +1420,7 @@ void seq_cache_put(const SeqRenderData *context,
}
/* Prevent reinserting, it breaks cache key linking. */
- ImBuf *test = seq_cache_get(context, seq, timeline_frame, type, true);
+ ImBuf *test = seq_cache_get(context, seq, timeline_frame, type);
if (test) {
IMB_freeImBuf(test);
return;
@@ -1370,63 +1431,12 @@ void seq_cache_put(const SeqRenderData *context,
}
seq_cache_lock(scene);
-
SeqCache *cache = seq_cache_get_from_scene(scene);
- int flag;
-
- if (seq->cache_flag & SEQ_CACHE_OVERRIDE) {
- flag = seq->cache_flag;
- /* Final_out is invalid in context of sequence override. */
- flag -= seq->cache_flag & SEQ_CACHE_STORE_FINAL_OUT;
- /* If global setting is enabled however, use it. */
- flag |= scene->ed->cache_flag & SEQ_CACHE_STORE_FINAL_OUT;
- }
- else {
- flag = scene->ed->cache_flag;
- }
-
- SeqCacheKey *key;
- key = BLI_mempool_alloc(cache->keys_pool);
- key->cache_owner = cache;
- key->seq = seq;
- key->context = *context;
- key->frame_index = seq_cache_timeline_frame_to_frame_index(seq, timeline_frame, type);
- key->timeline_frame = timeline_frame;
- key->type = type;
- key->link_prev = NULL;
- key->link_next = NULL;
- key->is_temp_cache = true;
- key->task_id = context->task_id;
-
- /* Item stored for later use */
- if (flag & type) {
- key->is_temp_cache = false;
- key->link_prev = cache->last_key;
- }
-
- SeqCacheKey *temp_last_key = cache->last_key;
- seq_cache_put_ex(cache, key, i);
-
- /* Restore pointer to previous item as this one will be freed when stack is rendered. */
- if (key->is_temp_cache) {
- cache->last_key = temp_last_key;
- }
-
- /* Set last_key's reference to this key so we can look up chain backwards.
- * Item is already put in cache, so cache->last_key points to current key.
- */
- if (flag & type && temp_last_key) {
- temp_last_key->link_next = cache->last_key;
- }
-
- /* Reset linking. */
- if (key->type == SEQ_CACHE_STORE_FINAL_OUT) {
- cache->last_key = NULL;
- }
-
+ SeqCacheKey *key = seq_cache_allocate_key(cache, context, seq, timeline_frame, type);
+ seq_cache_put_ex(scene, key, i);
seq_cache_unlock(scene);
- if (!key->is_temp_cache && !skip_disk_cache) {
+ if (!key->is_temp_cache) {
if (seq_disk_cache_is_enabled(context->bmain)) {
if (cache->disk_cache == NULL) {
seq_disk_cache_create(context->bmain, context->scene);
diff --git a/source/blender/sequencer/intern/image_cache.h b/source/blender/sequencer/intern/image_cache.h
index 41e8c4d1d48..63c559caee9 100644
--- a/source/blender/sequencer/intern/image_cache.h
+++ b/source/blender/sequencer/intern/image_cache.h
@@ -40,20 +40,17 @@ struct Sequence;
struct ImBuf *seq_cache_get(const struct SeqRenderData *context,
struct Sequence *seq,
float timeline_frame,
- int type,
- bool skip_disk_cache);
+ int type);
void seq_cache_put(const struct SeqRenderData *context,
struct Sequence *seq,
float timeline_frame,
int type,
- struct ImBuf *i,
- bool skip_disk_cache);
+ struct ImBuf *i);
bool seq_cache_put_if_possible(const struct SeqRenderData *context,
struct Sequence *seq,
float timeline_frame,
int type,
- struct ImBuf *nval,
- bool skip_disk_cache);
+ struct ImBuf *nval);
bool seq_cache_recycle_item(struct Scene *scene);
void seq_cache_free_temp_cache(struct Scene *scene, short id, int timeline_frame);
void seq_cache_destruct(struct Scene *scene);
diff --git a/source/blender/sequencer/intern/iterator.c b/source/blender/sequencer/intern/iterator.c
index bb4982d1468..f99667dea04 100644
--- a/source/blender/sequencer/intern/iterator.c
+++ b/source/blender/sequencer/intern/iterator.c
@@ -75,31 +75,31 @@ static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
}
static void seq_array(Editing *ed,
- Sequence ***seqarray,
- int *tot,
- const bool use_current_sequences)
+ const bool use_current_sequences,
+ Sequence ***r_seqarray,
+ int *r_seqarray_len)
{
Sequence **array;
- *seqarray = NULL;
- *tot = 0;
+ *r_seqarray = NULL;
+ *r_seqarray_len = 0;
if (ed == NULL) {
return;
}
if (use_current_sequences) {
- seq_count(ed->seqbasep, tot);
+ seq_count(ed->seqbasep, r_seqarray_len);
}
else {
- seq_count(&ed->seqbase, tot);
+ seq_count(&ed->seqbase, r_seqarray_len);
}
- if (*tot == 0) {
+ if (*r_seqarray_len == 0) {
return;
}
- *seqarray = array = MEM_mallocN(sizeof(Sequence *) * (*tot), "SeqArray");
+ *r_seqarray = array = MEM_mallocN(sizeof(Sequence *) * (*r_seqarray_len), "SeqArray");
if (use_current_sequences) {
seq_build_array(ed->seqbasep, &array, 0);
}
@@ -111,7 +111,7 @@ static void seq_array(Editing *ed,
void SEQ_iterator_begin(Editing *ed, SeqIterator *iter, const bool use_current_sequences)
{
memset(iter, 0, sizeof(*iter));
- seq_array(ed, &iter->array, &iter->tot, use_current_sequences);
+ seq_array(ed, use_current_sequences, &iter->array, &iter->tot);
if (iter->tot) {
iter->cur = 0;
diff --git a/source/blender/sequencer/intern/prefetch.c b/source/blender/sequencer/intern/prefetch.c
index b0e9e3c5003..4317fa3a850 100644
--- a/source/blender/sequencer/intern/prefetch.c
+++ b/source/blender/sequencer/intern/prefetch.c
@@ -379,28 +379,28 @@ static bool seq_prefetch_do_skip_frame(PrefetchJob *pfjob, ListBase *seqbase)
if (seq_arr[i]->type == SEQ_TYPE_SCENE && (seq_arr[i]->flag & SEQ_SCENE_STRIPS) == 0) {
int cached_types = 0;
- ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_FINAL_OUT, false);
+ ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_FINAL_OUT);
if (ibuf != NULL) {
cached_types |= SEQ_CACHE_STORE_FINAL_OUT;
IMB_freeImBuf(ibuf);
ibuf = NULL;
}
- ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, false);
+ ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE);
if (ibuf != NULL) {
cached_types |= SEQ_CACHE_STORE_COMPOSITE;
IMB_freeImBuf(ibuf);
ibuf = NULL;
}
- ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_PREPROCESSED, false);
+ ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_PREPROCESSED);
if (ibuf != NULL) {
cached_types |= SEQ_CACHE_STORE_PREPROCESSED;
IMB_freeImBuf(ibuf);
ibuf = NULL;
}
- ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_RAW, false);
+ ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_RAW);
if (ibuf != NULL) {
cached_types |= SEQ_CACHE_STORE_RAW;
IMB_freeImBuf(ibuf);
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index 0ab2a67e560..e9de73bc093 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -599,10 +599,12 @@ static void multibuf(ImBuf *ibuf, const float fmul)
}
}
-/* Effect, mask and scene in strip input strips are rendered in preview resolution. They are
- * already downscaled. input_preprocess() does not expect this to happen. Other strip types are
- * rendered with original media resolution, unless proxies are enabled for them. With proxies
- * is_proxy_image will be set correctly to true.*/
+/**
+ * Effect, mask and scene in strip input strips are rendered in preview resolution.
+ * They are already down-scaled. #input_preprocess() does not expect this to happen.
+ * Other strip types are rendered with original media resolution, unless proxies are
+ * enabled for them. With proxies `is_proxy_image` will be set correctly to true.
+ */
static bool seq_need_scale_to_render_size(const Sequence *seq, bool is_proxy_image)
{
if (is_proxy_image) {
@@ -762,14 +764,14 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
/* Proxies and effect strips are not stored in cache. */
if (!is_proxy_image && (seq->type & SEQ_TYPE_EFFECT) == 0) {
- seq_cache_put(context, seq, timeline_frame, SEQ_CACHE_STORE_RAW, ibuf, false);
+ seq_cache_put(context, seq, timeline_frame, SEQ_CACHE_STORE_RAW, ibuf);
}
if (use_preprocess) {
ibuf = input_preprocess(context, seq, timeline_frame, ibuf, is_proxy_image);
}
- seq_cache_put(context, seq, timeline_frame, SEQ_CACHE_STORE_PREPROCESSED, ibuf, false);
+ seq_cache_put(context, seq, timeline_frame, SEQ_CACHE_STORE_PREPROCESSED, ibuf);
return ibuf;
}
@@ -1637,8 +1639,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
}
if (view_id != context->view_id) {
- seq_cache_put(
- &localcontext, seq, timeline_frame, SEQ_CACHE_STORE_RAW, ibufs_arr[view_id], false);
+ seq_cache_put(&localcontext, seq, timeline_frame, SEQ_CACHE_STORE_RAW, ibufs_arr[view_id]);
}
RE_ReleaseResultImage(re);
@@ -1813,14 +1814,14 @@ ImBuf *seq_render_strip(const SeqRenderData *context,
bool use_preprocess = false;
bool is_proxy_image = false;
- ibuf = seq_cache_get(context, seq, timeline_frame, SEQ_CACHE_STORE_PREPROCESSED, false);
+ ibuf = seq_cache_get(context, seq, timeline_frame, SEQ_CACHE_STORE_PREPROCESSED);
if (ibuf != NULL) {
return ibuf;
}
/* Proxies are not stored in cache. */
if (!SEQ_can_use_proxy(seq, SEQ_rendersize_to_proxysize(context->preview_render_size))) {
- ibuf = seq_cache_get(context, seq, timeline_frame, SEQ_CACHE_STORE_RAW, false);
+ ibuf = seq_cache_get(context, seq, timeline_frame, SEQ_CACHE_STORE_RAW);
}
if (ibuf == NULL) {
@@ -1927,7 +1928,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
int early_out;
Sequence *seq = seq_arr[i];
- out = seq_cache_get(context, seq, timeline_frame, SEQ_CACHE_STORE_COMPOSITE, false);
+ out = seq_cache_get(context, seq, timeline_frame, SEQ_CACHE_STORE_COMPOSITE);
if (out) {
break;
@@ -1956,8 +1957,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
out = seq_render_strip_stack_apply_effect(context, seq, timeline_frame, ibuf1, ibuf2);
- seq_cache_put(
- context, seq_arr[i], timeline_frame, SEQ_CACHE_STORE_COMPOSITE, out, false);
+ seq_cache_put(context, seq_arr[i], timeline_frame, SEQ_CACHE_STORE_COMPOSITE, out);
IMB_freeImBuf(ibuf1);
IMB_freeImBuf(ibuf2);
@@ -1983,7 +1983,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
IMB_freeImBuf(ibuf2);
}
- seq_cache_put(context, seq_arr[i], timeline_frame, SEQ_CACHE_STORE_COMPOSITE, out, false);
+ seq_cache_put(context, seq_arr[i], timeline_frame, SEQ_CACHE_STORE_COMPOSITE, out);
}
return out;
@@ -2022,8 +2022,7 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
count = seq_get_shown_sequences(seqbasep, timeline_frame, chanshown, seq_arr);
if (count) {
- out = seq_cache_get(
- context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT, false);
+ out = seq_cache_get(context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT);
}
seq_cache_free_temp_cache(context->scene, context->task_id, timeline_frame);
@@ -2033,12 +2032,11 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
out = seq_render_strip_stack(context, &state, seqbasep, timeline_frame, chanshown);
if (context->is_prefetch_render) {
- seq_cache_put(
- context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT, out, false);
+ seq_cache_put(context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT, out);
}
else {
seq_cache_put_if_possible(
- context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT, out, false);
+ context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT, out);
}
BLI_mutex_unlock(&seq_render_mutex);
}
diff --git a/source/blender/sequencer/intern/strip_select.c b/source/blender/sequencer/intern/strip_select.c
index 58ae281ead1..7cdd756e2d9 100644
--- a/source/blender/sequencer/intern/strip_select.c
+++ b/source/blender/sequencer/intern/strip_select.c
@@ -54,29 +54,29 @@ void SEQ_select_active_set(Scene *scene, Sequence *seq)
ed->act_seq = seq;
}
-int SEQ_select_active_get_pair(Scene *scene, Sequence **seq_act, Sequence **seq_other)
+int SEQ_select_active_get_pair(Scene *scene, Sequence **r_seq_act, Sequence **r_seq_other)
{
Editing *ed = SEQ_editing_get(scene, false);
- *seq_act = SEQ_select_active_get(scene);
+ *r_seq_act = SEQ_select_active_get(scene);
- if (*seq_act == NULL) {
+ if (*r_seq_act == NULL) {
return 0;
}
Sequence *seq;
- *seq_other = NULL;
+ *r_seq_other = NULL;
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (seq->flag & SELECT && (seq != (*seq_act))) {
- if (*seq_other) {
+ if (seq->flag & SELECT && (seq != (*r_seq_act))) {
+ if (*r_seq_other) {
return 0;
}
- *seq_other = seq;
+ *r_seq_other = seq;
}
}
- return (*seq_other != NULL);
+ return (*r_seq_other != NULL);
}
diff --git a/source/blender/simulation/intern/implicit_blender.c b/source/blender/simulation/intern/implicit_blender.c
index 4c4d3e8a821..cf092d7716a 100644
--- a/source/blender/simulation/intern/implicit_blender.c
+++ b/source/blender/simulation/intern/implicit_blender.c
@@ -1693,7 +1693,7 @@ BLI_INLINE void dfdx_damp(float to[3][3],
BLI_INLINE void dfdv_damp(float to[3][3], const float dir[3], float damping)
{
- /* derivative of force wrt velocity */
+ /* Derivative of force with regards to velocity. */
outerproduct(to, dir, dir);
mul_m3_fl(to, -damping);
}
@@ -1727,7 +1727,7 @@ BLI_INLINE float fbstar(float length, float L, float kb, float cb)
return tempfb_fl;
}
-/* function to calculae bending spring force (taken from Choi & Co) */
+/* Function to calculate bending spring force (taken from Choi & Co). */
BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
{
float tempfb_fl = kb * fb(length, L);
diff --git a/source/blender/simulation/intern/implicit_eigen.cpp b/source/blender/simulation/intern/implicit_eigen.cpp
index ea1729589d6..8eb227d38ab 100644
--- a/source/blender/simulation/intern/implicit_eigen.cpp
+++ b/source/blender/simulation/intern/implicit_eigen.cpp
@@ -904,7 +904,7 @@ BLI_INLINE void dfdx_damp(float to[3][3],
BLI_INLINE void dfdv_damp(float to[3][3], const float dir[3], float damping)
{
- /* derivative of force wrt velocity */
+ /* Derivative of force with regards to velocity. */
outerproduct(to, dir, dir);
mul_m3_fl(to, -damping);
}
@@ -936,7 +936,7 @@ BLI_INLINE float fbstar(float length, float L, float kb, float cb)
}
}
-/* function to calculae bending spring force (taken from Choi & Co) */
+/* Function to calculate bending spring force (taken from Choi & Co). */
BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
{
float tempfb_fl = kb * fb(length, L);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 540896664da..69177f39c04 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -685,6 +685,7 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
void WM_drag_add_local_ID(struct wmDrag *drag, struct ID *id, struct ID *from_parent);
struct ID *WM_drag_get_local_ID(const struct wmDrag *drag, short idcode);
struct ID *WM_drag_get_local_ID_from_event(const struct wmEvent *event, short idcode);
+bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode);
struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode);
struct ID *WM_drag_get_local_ID_or_import_from_asset(const struct wmDrag *drag, int idcode);
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
index 15be21bdbc4..564afe084b9 100644
--- a/source/blender/windowmanager/WM_keymap.h
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -59,7 +59,7 @@ wmKeyMapItem *WM_keymap_add_item(
wmKeyMapItem *WM_keymap_add_item_copy(struct wmKeyMap *keymap, wmKeyMapItem *kmi_src);
bool WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
-int WM_keymap_item_to_string(wmKeyMapItem *kmi,
+int WM_keymap_item_to_string(const wmKeyMapItem *kmi,
const bool compact,
char *result,
const int result_len);
@@ -86,7 +86,7 @@ bool WM_keymap_remove(struct wmKeyConfig *keyconfig, struct wmKeyMap *keymap);
bool WM_keymap_poll(struct bContext *C, struct wmKeyMap *keymap);
wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id);
-bool WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2);
+bool WM_keymap_item_compare(const struct wmKeyMapItem *k1, const struct wmKeyMapItem *k2);
/* keymap_utils.c */
@@ -111,13 +111,13 @@ void WM_keymap_add_context_enum_set_items(wmKeyMap *keymap,
wmKeyMap *WM_keymap_guess_from_context(const struct bContext *C);
wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname);
-bool WM_keymap_uses_event_modifier(wmKeyMap *keymap, const int event_modifier);
+bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier);
void WM_keymap_fix_linking(void);
/* Modal Keymap */
-int WM_modalkeymap_items_to_string(struct wmKeyMap *km,
+int WM_modalkeymap_items_to_string(const struct wmKeyMap *km,
const int propvalue,
const bool compact,
char *result,
@@ -142,7 +142,7 @@ wmKeyMapItem *WM_modalkeymap_add_item(
struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value);
wmKeyMapItem *WM_modalkeymap_add_item_str(
struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value);
-wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue);
+const wmKeyMapItem *WM_modalkeymap_find_propvalue(const wmKeyMap *km, const int propvalue);
void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname);
/* Keymap Editor */
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_api.h b/source/blender/windowmanager/gizmo/WM_gizmo_api.h
index 70ddae4d724..cf1a7628267 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_api.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_api.h
@@ -301,7 +301,7 @@ void WM_gizmomap_draw(struct wmGizmoMap *gzmap,
void WM_gizmomap_add_handlers(struct ARegion *region, struct wmGizmoMap *gzmap);
bool WM_gizmomap_select_all(struct bContext *C, struct wmGizmoMap *gzmap, const int action);
bool WM_gizmomap_cursor_set(const struct wmGizmoMap *gzmap, struct wmWindow *win);
-void WM_gizmomap_message_subscribe(struct bContext *C,
+void WM_gizmomap_message_subscribe(const struct bContext *C,
struct wmGizmoMap *gzmap,
struct ARegion *region,
struct wmMsgBus *mbus);
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
index 8f84c02be12..fd7f9c2de7c 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
@@ -371,6 +371,14 @@ typedef struct wmGizmoType {
*/
wmGizmoFnMatrixBasisGet matrix_basis_get;
+ /**
+ * Returns screen-space bounding box in the window space
+ * (compatible with #wmEvent.x #wmEvent.y).
+ *
+ * Used for tool-tip placement (otherwise the cursor location is used).
+ */
+ wmGizmoFnScreenBoundsGet screen_bounds_get;
+
/** Activate a gizmo state when the user clicks on it. */
wmGizmoFnInvoke invoke;
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 479768c3536..12c6eb46c12 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -1156,7 +1156,7 @@ ListBase *wm_gizmomap_groups_get(wmGizmoMap *gzmap)
return &gzmap->groups;
}
-void WM_gizmomap_message_subscribe(bContext *C,
+void WM_gizmomap_message_subscribe(const bContext *C,
wmGizmoMap *gzmap,
ARegion *region,
struct wmMsgBus *mbus)
diff --git a/source/blender/windowmanager/gizmo/wm_gizmo_fn.h b/source/blender/windowmanager/gizmo/wm_gizmo_fn.h
index 418e848e35b..84e6308223f 100644
--- a/source/blender/windowmanager/gizmo/wm_gizmo_fn.h
+++ b/source/blender/windowmanager/gizmo/wm_gizmo_fn.h
@@ -62,6 +62,9 @@ typedef void (*wmGizmoFnMatrixBasisGet)(const struct wmGizmo *, float[4][4]);
typedef int (*wmGizmoFnInvoke)(struct bContext *, struct wmGizmo *, const struct wmEvent *);
typedef void (*wmGizmoFnExit)(struct bContext *, struct wmGizmo *, const bool);
typedef int (*wmGizmoFnCursorGet)(struct wmGizmo *);
+typedef void (*wmGizmoFnScreenBoundsGet)(struct bContext *,
+ struct wmGizmo *,
+ rcti *r_bounding_box);
typedef void (*wmGizmoFnSelectRefresh)(struct wmGizmo *);
typedef void (*wmGizmoFnFree)(struct wmGizmo *);
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index a10284e9740..549b59e9e1d 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -279,6 +279,8 @@ IDTypeInfo IDType_ID_WM = {
.blend_read_expand = NULL,
.blend_read_undo_preserve = NULL,
+
+ .lib_override_apply_post = NULL,
};
#define MAX_OP_REGISTERED 32
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index d50516dfab2..e32552063af 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -246,8 +246,7 @@ void WM_cursor_wait(bool val)
void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
{
/* Only grab cursor when not running debug.
- * It helps not to get a stuck WM when hitting a breakpoint
- * */
+ * It helps not to get a stuck WM when hitting a break-point. */
GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
GHOST_TAxisFlag mode_axis = GHOST_kAxisX | GHOST_kGrabAxisY;
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 08f60fef0d2..6fdcbab889c 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -225,7 +225,8 @@ static const char *dropbox_active(bContext *C,
if (handler->dropboxes) {
LISTBASE_FOREACH (wmDropBox *, drop, handler->dropboxes) {
const char *tooltip = NULL;
- if (drop->poll(C, drag, event, &tooltip)) {
+ if (drop->poll(C, drag, event, &tooltip) &&
+ WM_operator_poll_context(C, drop->ot, drop->opcontext)) {
/* XXX Doing translation here might not be ideal, but later we have no more
* access to ot (and hence op context)... */
return (tooltip) ? tooltip : WM_operatortype_name(drop->ot, drop->ptr);
@@ -353,6 +354,14 @@ ID *WM_drag_get_local_ID_from_event(const wmEvent *event, short idcode)
return WM_drag_get_local_ID(lb->first, idcode);
}
+/**
+ * Check if the drag data is either a local ID or an external ID asset of type \a idcode.
+ */
+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_get_asset_data(const wmDrag *drag, int idcode)
{
if (drag->type != WM_DRAG_ASSET) {
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index b11dae27d19..85611a0be93 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -346,7 +346,7 @@ static const char *wm_area_name(ScrArea *area)
SPACE_NAME(SPACE_TOPBAR);
SPACE_NAME(SPACE_STATUSBAR);
default:
- return "Unkown Space";
+ return "Unknown Space";
}
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 859336d0338..e132caede0d 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -543,13 +543,33 @@ void wm_event_do_notifiers(bContext *C)
ED_screen_do_listen(C, note);
LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
- ED_region_do_listen(win, NULL, region, note, scene);
+ wmRegionListenerParams region_params = {
+ .window = win,
+ .area = NULL,
+ .region = region,
+ .scene = scene,
+ .notifier = note,
+ };
+ ED_region_do_listen(&region_params);
}
ED_screen_areas_iter (win, screen, area) {
- ED_area_do_listen(win, area, note, scene);
+ wmSpaceTypeListenerParams area_params = {
+ .window = win,
+ .area = area,
+ .notifier = note,
+ .scene = scene,
+ };
+ ED_area_do_listen(&area_params);
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
- ED_region_do_listen(win, area, region, note, scene);
+ wmRegionListenerParams region_params = {
+ .window = win,
+ .area = area,
+ .region = region,
+ .scene = scene,
+ .notifier = note,
+ };
+ ED_region_do_listen(&region_params);
}
}
}
@@ -2079,7 +2099,7 @@ static int wm_handler_operator_call(bContext *C,
handler->op = NULL;
}
- /* Putting back screen context, reval can pass trough after modal failures! */
+ /* Putting back screen context, reval can pass through after modal failures! */
if ((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
@@ -2788,8 +2808,10 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
LISTBASE_FOREACH (wmDrag *, drag, lb) {
const char *tooltip = NULL;
if (drop->poll(C, drag, event, &tooltip)) {
- /* Optionally copy drag information to operator properties. */
- if (drop->copy) {
+ /* Optionally copy drag information to operator properties. Don't call it if the
+ * operator fails anyway, it might do more than just set properties (e.g.
+ * typically import an asset). */
+ if (drop->copy && WM_operator_poll_context(C, drop->ot, drop->opcontext)) {
drop->copy(drag, drop);
}
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 8bfec0dc5c9..fcb13fff0a5 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -949,9 +949,9 @@ wmKeyMapItem *WM_modalkeymap_add_item_str(
return kmi;
}
-static wmKeyMapItem *wm_modalkeymap_find_propvalue_iter(wmKeyMap *km,
- wmKeyMapItem *kmi,
- const int propvalue)
+static const wmKeyMapItem *wm_modalkeymap_find_propvalue_iter(const wmKeyMap *km,
+ const wmKeyMapItem *kmi,
+ const int propvalue)
{
if (km->flag & KEYMAP_MODAL) {
kmi = kmi ? kmi->next : km->items.first;
@@ -968,7 +968,7 @@ static wmKeyMapItem *wm_modalkeymap_find_propvalue_iter(wmKeyMap *km,
return NULL;
}
-wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue)
+const wmKeyMapItem *WM_modalkeymap_find_propvalue(const wmKeyMap *km, const int propvalue)
{
return wm_modalkeymap_find_propvalue_iter(km, NULL, propvalue);
}
@@ -1201,7 +1201,7 @@ int WM_keymap_item_raw_to_string(const short shift,
#undef ADD_SEP
}
-int WM_keymap_item_to_string(wmKeyMapItem *kmi,
+int WM_keymap_item_to_string(const wmKeyMapItem *kmi,
const bool compact,
char *result,
const int result_len)
@@ -1218,14 +1218,17 @@ int WM_keymap_item_to_string(wmKeyMapItem *kmi,
result_len);
}
-int WM_modalkeymap_items_to_string(
- wmKeyMap *km, const int propvalue, const bool compact, char *result, const int result_len)
+int WM_modalkeymap_items_to_string(const wmKeyMap *km,
+ const int propvalue,
+ const bool compact,
+ char *result,
+ const int result_len)
{
int totlen = 0;
bool add_sep = false;
if (km) {
- wmKeyMapItem *kmi;
+ const wmKeyMapItem *kmi;
/* Find all shortcuts related to that propvalue! */
for (kmi = WM_modalkeymap_find_propvalue(km, propvalue); kmi && totlen < (result_len - 2);
@@ -1654,7 +1657,7 @@ wmKeyMapItem *WM_key_event_operator_from_keymap(wmKeyMap *keymap,
});
}
-bool WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2)
+bool WM_keymap_item_compare(const wmKeyMapItem *k1, const wmKeyMapItem *k2)
{
if (k1->flag & KMI_INACTIVE || k2->flag & KMI_INACTIVE) {
return 0;
diff --git a/source/blender/windowmanager/intern/wm_keymap_utils.c b/source/blender/windowmanager/intern/wm_keymap_utils.c
index 953fb9fed79..865889e7e64 100644
--- a/source/blender/windowmanager/intern/wm_keymap_utils.c
+++ b/source/blender/windowmanager/intern/wm_keymap_utils.c
@@ -477,7 +477,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
return km;
}
-static bool wm_keymap_item_uses_modifier(wmKeyMapItem *kmi, const int event_modifier)
+static bool wm_keymap_item_uses_modifier(const wmKeyMapItem *kmi, const int event_modifier)
{
if (kmi->ctrl != KM_ANY) {
if ((kmi->ctrl == KM_NOTHING) != ((event_modifier & KM_CTRL) == 0)) {
@@ -505,9 +505,9 @@ static bool wm_keymap_item_uses_modifier(wmKeyMapItem *kmi, const int event_modi
return true;
}
-bool WM_keymap_uses_event_modifier(wmKeyMap *keymap, const int event_modifier)
+bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier)
{
- LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
+ LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &keymap->items) {
if ((kmi->flag & KMI_INACTIVE) == 0) {
if (wm_keymap_item_uses_modifier(kmi, event_modifier)) {
return true;
diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c
index 8dfe26fbf79..aeab1ee6fca 100644
--- a/source/blender/windowmanager/intern/wm_operator_props.c
+++ b/source/blender/windowmanager/intern/wm_operator_props.c
@@ -284,15 +284,15 @@ void WM_operator_properties_select_action_simple(wmOperatorType *ot,
*/
void WM_operator_properties_select_random(wmOperatorType *ot)
{
- RNA_def_float_percentage(ot->srna,
- "percent",
- 50.0f,
- 0.0f,
- 100.0f,
- "Percent",
- "Percentage of objects to select randomly",
- 0.0f,
- 100.0f);
+ RNA_def_float_factor(ot->srna,
+ "ratio",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Ratio",
+ "Portion of items to select randomly",
+ 0.f,
+ 1.0f);
RNA_def_int(ot->srna,
"seed",
0,
diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c
index 4c4fd2b1a8e..0e57a92b685 100644
--- a/source/blender/windowmanager/intern/wm_operator_type.c
+++ b/source/blender/windowmanager/intern/wm_operator_type.c
@@ -424,9 +424,8 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
wm_event_free_handler(&handler->head);
}
- /* if operator is blocking, grab cursor
- * This may end up grabbing twice, but we don't care.
- * */
+ /* If operator is blocking, grab cursor.
+ * This may end up grabbing twice, but we don't care. */
if (op->opm->type->flag & OPTYPE_BLOCKING) {
int bounds[4] = {-1, -1, -1, -1};
int wrap = WM_CURSOR_WRAP_NONE;
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 60bcb687dbf..1b1ebc70fd9 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -1097,6 +1097,7 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
posy = (scr_h - posy - sizey);
g_WS.ghost_window = GHOST_CreateWindow(g_WS.ghost_system,
+ NULL,
title,
posx,
posy,
@@ -1104,6 +1105,7 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
sizey,
/* could optionally start fullscreen */
GHOST_kWindowStateNormal,
+ false,
GHOST_kDrawingContextTypeOpenGL,
glsettings);
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 42fd214543f..6433cd7d12d 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -560,7 +560,6 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
wmWindow *win,
bool is_dialog)
{
-
/* a new window is created when pageflip mode is required for a window */
GHOST_GLSettings glSettings = {0};
if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) {
@@ -579,30 +578,17 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
wmWindow *prev_windrawable = wm->windrawable;
wm_window_clear_drawable(wm);
- GHOST_WindowHandle ghostwin;
- if (is_dialog && win->parent) {
- ghostwin = GHOST_CreateDialogWindow(g_system,
- win->parent->ghostwin,
- title,
- win->posx,
- posy,
- win->sizex,
- win->sizey,
- (GHOST_TWindowState)win->windowstate,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
- }
- else {
- ghostwin = GHOST_CreateWindow(g_system,
- title,
- win->posx,
- posy,
- win->sizex,
- win->sizey,
- (GHOST_TWindowState)win->windowstate,
- GHOST_kDrawingContextTypeOpenGL,
- glSettings);
- }
+ GHOST_WindowHandle ghostwin = GHOST_CreateWindow(g_system,
+ (win->parent) ? win->parent->ghostwin : NULL,
+ title,
+ win->posx,
+ posy,
+ win->sizex,
+ win->sizey,
+ (GHOST_TWindowState)win->windowstate,
+ is_dialog,
+ GHOST_kDrawingContextTypeOpenGL,
+ glSettings);
if (ghostwin) {
win->gpuctx = GPU_context_create(ghostwin);
@@ -858,13 +844,15 @@ wmWindow *WM_window_open_temp(bContext *C,
/* changes rect to fit within desktop */
wm_window_check_position(&rect);
- /* Reuse temporary or dialog window if one is open (but don't use a dialog for a regular
- * temporary window, or vice versa). */
+ /* Reuse temporary windows when they share the same title. */
wmWindow *win = NULL;
LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) {
- if (WM_window_is_temp_screen(win_iter) &&
- (dialog == GHOST_IsDialogWindow(win_iter->ghostwin))) {
- win = win_iter;
+ if (WM_window_is_temp_screen(win_iter)) {
+ char *wintitle = GHOST_GetTitle(win_iter->ghostwin);
+ if (strcmp(title, wintitle) == 0) {
+ win = win_iter;
+ }
+ free(wintitle);
}
}
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_draw.c b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
index 499ec136e03..cc4a7e41e82 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_draw.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
@@ -129,7 +129,7 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
/* Some systems have drawing glitches without this. */
GPU_clear_depth(1.0f);
- /* Draws the view into the surface_data->viewport's framebuffers */
+ /* Draws the view into the surface_data->viewport's frame-buffers. */
ED_view3d_draw_offscreen_simple(draw_data->depsgraph,
draw_data->scene,
&settings->shading,
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 7db936b3e51..fd1d721d869 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -74,7 +74,7 @@ endif()
if(WITH_TBB)
blender_include_dirs(${TBB_INCLUDE_DIRS})
if(NOT APPLE)
- # APPLE plaform uses full paths for linking libraries.
+ # APPLE platform uses full paths for linking libraries.
link_directories(${LIBDIR}/tbb/lib)
endif()
endif()
@@ -764,7 +764,7 @@ elseif(WIN32)
PATTERN "*.pyo" EXCLUDE # * any cache *
)
- install(
+ install(
DIRECTORY ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/lib
DESTINATION ${BLENDER_VERSION}/python/
CONFIGURATIONS Debug
@@ -772,7 +772,6 @@ elseif(WIN32)
PATTERN "__pycache__" EXCLUDE # * any cache *
PATTERN "*.pyc" EXCLUDE # * any cache *
PATTERN "*.pyo" EXCLUDE # * any cache *)
-
)
install(
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index 6836cbec18c..e31be24ec7b 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -590,8 +590,6 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
BLI_args_print_arg_doc(ba, "--debug-ghost");
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-shaders");
- BLI_args_print_arg_doc(ba, "--debug-gpumem");
BLI_args_print_arg_doc(ba, "--debug-wm");
# ifdef WITH_XR_OPENXR
BLI_args_print_arg_doc(ba, "--debug-xr");
@@ -988,9 +986,9 @@ static const char arg_handle_debug_mode_generic_set_doc_depsgraph_no_threads[] =
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_pretty[] =
"\n\t"
"Enable colors for dependency graph debug messages.";
-static const char arg_handle_debug_mode_generic_set_doc_gpumem[] =
+static const char arg_handle_debug_mode_generic_set_doc_gpu_force_workarounds[] =
"\n\t"
- "Enable GPU memory stats in status bar.";
+ "Enable workarounds for typical GPU issues and disable all GPU extensions.";
static int arg_handle_debug_mode_generic_set(int UNUSED(argc),
const char **UNUSED(argv),
@@ -1160,7 +1158,7 @@ static int arg_handle_env_system_set(int argc, const char **argv, void *UNUSED(d
}
for (; *ch_src; ch_src++, ch_dst++) {
- *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* toupper() */
+ *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* Inline #toupper() */
}
*ch_dst = '\0';
@@ -1958,7 +1956,7 @@ static int arg_handle_load_file(int UNUSED(argc), const char **argv, void *data)
if (success) {
if (G.background) {
- /* ensuer we use 'C->data.scene' for background render */
+ /* Ensure we use 'C->data.scene' for background render. */
CTX_wm_window_set(C, NULL);
}
}
@@ -2170,18 +2168,8 @@ void main_args_setup(bContext *C, bArgs *ba)
(void *)G_DEBUG_DEPSGRAPH_UUID);
BLI_args_add(ba,
NULL,
- "--debug-gpumem",
- CB_EX(arg_handle_debug_mode_generic_set, gpumem),
- (void *)G_DEBUG_GPU_MEM);
- BLI_args_add(ba,
- NULL,
- "--debug-gpu-shaders",
- CB_EX(arg_handle_debug_mode_generic_set, gpumem),
- (void *)G_DEBUG_GPU_SHADERS);
- BLI_args_add(ba,
- NULL,
"--debug-gpu-force-workarounds",
- CB_EX(arg_handle_debug_mode_generic_set, gpumem),
+ CB_EX(arg_handle_debug_mode_generic_set, gpu_force_workarounds),
(void *)G_DEBUG_GPU_FORCE_WORKAROUNDS);
BLI_args_add(ba, NULL, "--debug-exit-on-error", CB(arg_handle_debug_exit_on_error), NULL);
diff --git a/tests/gtests/runner/CMakeLists.txt b/tests/gtests/runner/CMakeLists.txt
index 85b80979074..1fe8cf21810 100644
--- a/tests/gtests/runner/CMakeLists.txt
+++ b/tests/gtests/runner/CMakeLists.txt
@@ -62,12 +62,31 @@ if(WIN32)
target_link_options(blender_test PRIVATE /wholearchive:$<TARGET_FILE:${_lib}>)
endforeach()
elseif(APPLE)
+ # force_load for `_test_libs` ensures that all symbols definitely make it into the test binary.
+ # But linking against them again using `target_link_libraries` creates duplicate symbol
+ # errors when linker cannot deduplicate a force loaded and linked library.
+ # So force load test libraries separately, and link against their non-"test libraries"
+ # dependencies separately.
+
+ # Gather dependencies of all test libraries.
+ set(_test_libs_dependencies)
foreach(_lib ${_test_libs})
- # We need -force_load for every test library and target_link_libraries will
- # deduplicate it. So explicitly set as linker option for every test lib.
- target_link_libraries(blender_test ${_lib})
+ get_target_property(_interface_libs ${_lib} INTERFACE_LINK_LIBRARIES)
+ if(_interface_libs)
+ list(APPEND _test_libs_dependencies ${_interface_libs})
+ endif()
+ unset(_interface_libs)
+ endforeach()
+
+ # Force load test libraries. Ensure that they are not linked twice in case they
+ # are used as dependencies of other test libraries.
+ foreach(_lib ${_test_libs})
+ list(REMOVE_ITEM _test_libs_dependencies ${_lib})
target_link_options(blender_test PRIVATE "LINKER:-force_load,$<TARGET_FILE:${_lib}>")
endforeach()
+
+ target_link_libraries(blender_test "${_test_libs_dependencies}")
+ unset(_test_libs_dependencies)
endif()
unset(_test_libs)